RemoteDataAdapter.DataRequestCall Example

Can you provide an expanded / working example of the use of DataRequestCall (ideally in .NET / Oxygene).

I have been looking at this thread and this one . I can get the client to make the call into the server using a custom method but I’m having trouble both getting custom parameters into the method and also the schema for the returned data table not being recognised when it is returned to the client.

A small fully working sample would be ideal as there appears to be virtually no documentation around this area.

Thanks,

Paul.

Hello

So, let’s assume that server has definition of such data access method:
public Binary CustomGetData(string table, string filter)
{
try
{
this.AllowExecuteSQL = true;

			var sql = "SELECT * FROM " + table; // Do not do such thing in a real project

			using (var command = this.Connection.NewCommand(sql))
			{
				using (var reader = command.ExecuteReader())
				{
					var result = new Binary();

					this.ServiceDataStreamer.InitializeStreamer(result, StreamerInitialization.Write);
					try
					{
						this.ServiceDataStreamer.WriteDataReader(reader, Schema.DeriveDataReaderSchema(reader, table), -1, true);
					}
					finally
					{
						this.ServiceDataStreamer.FinalizeStreamer();
					}

					return result;
				}
			}
		}
		finally
		{
			this.AllowExecuteSQL = false;
		}
	}

Then acquiring data via this method would like (in the real project request initialization should be encapsulated in a class descended from the RemoteDataAdapter class):

using System;
using System.Data;
using RemObjects.DataAbstract;
using RemObjects.SDK;

namespace CustomClient
{
	static class Program
	{
		static void Main(string[] args)
		{
			try
			{
				// Usual connect initialization
				var channel = ClientChannel.ChannelMatchingTargetUri("http://localhost:8099/bin");
				var message = Message.MessageMatchingTargetUri("http://localhost:8099/bin");

				var remoteService = new RemoteService(message, channel, true, "DataService");
				var streamer = new Bin2DataStreamer();

				var dataAdapter = new RemoteDataAdapter { RemoteService = remoteService, DataStreamer = streamer };


				// Define own GetData call
				dataAdapter.DataRequestCall.MethodName = "CustomGetData";
				dataAdapter.DataRequestCall.Parameters.Clear();
				dataAdapter.DataRequestCall.Parameters.Add("table", "Utf8String", RemObjects.SDK.ParameterDirection.In);
				dataAdapter.DataRequestCall.Parameters.Add("filter", "Utf8String", RemObjects.SDK.ParameterDirection.In);
				dataAdapter.DataRequestCall.Parameters.Add("Result", "Binary", RemObjects.SDK.ParameterDirection.Result);

				dataAdapter.DataRequestCall.IncomingDataParameter = "Result";
				dataAdapter.DataRequestCall.OutgoingTableNamesParameter = "";


				// Provide method parameter values
				dataAdapter.DataRequestCall.Parameters.ParameterByName("table").Value = "OrderDetails";
				dataAdapter.DataRequestCall.Parameters.ParameterByName("filter").Value = "Some Value";

				// Get data
				var ds = new DataSet();
				var data = new DataTable("OrderDetails");
				ds.Tables.Add(data);
				dataAdapter.Fill(ds, true);

				// Show acquired data
				Console.WriteLine("Rows retrieved: " + data.Rows.Count);

				foreach (DataRow row in data.Rows)
				{
					Console.WriteLine(row[0].ToString());
				}

				Console.WriteLine("Data Flushed");
				Console.WriteLine();
				Console.WriteLine("Column names:");
				foreach (DataColumn column in data.Columns)
				{
					Console.WriteLine(column.ColumnName);
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex.ToString());
			}
			Console.ReadKey();
		}
	}
}

It is also possible to manually call the service method and deserialize acquired data using the DataStreamer methods (similar to the one used to serialize the data)

Regards

Hello Anton,

Thanks for the reply. I did manage to get the custom method working shortly before your reply, but I’m still glad of the example - I’ll be using the Schema.DeriveDataReaderSchema instead of the manual creation of field and table schema data for the custom data I am returning. I’ll probably also make use of the AllowExecuteSQL property instead of the separate MSSQL.NET connection that I am currently using.

The key part I had been missing was the use of the overloaded WriteDataReader method - the one that includes the Boolean to indicate whether the schema should be returned or not. The version of the custom call Andrey quoted from last year did not make use of that overload.

The other issue I had about passing parameters into the call was my mistake. For some reason I was trying to pass Int32 types and not Integer.

Thanks Again,

Paul.