Tải bản đầy đủ (.pdf) (10 trang)

Updating Server Data Using .NET Remoting

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (27.64 KB, 10 trang )

[ Team LiB ]


Recipe 4.12 Updating Server Data Using .NET Remoting
Problem
You want to update a data source using .NET remoting and use the remote application
from your client application.
Solution
Use System.MarshalByRefObject to create a remoteable class.
The server-side code that registers the remoteable class for remote activation contains one
event handler and one configuration file:
Start Server Button.Click
Registers the remoteable class RemoteClass for remote activation.
Server-side configuration file
Contains parameters used to register the class and the channel on the server so that
the class can be activated from another application domain.
The remoteable class code contains two methods:
LoadOrders( )
Creates and returns a DataSet containing the Orders and Order Details tables from
Northwind and a DataRelation between those tables.
UpdateOrders( )
Takes a DataSet argument containing the changes made to the DataSet created by
the LoadOrders( ) method, creates two DataAdapter objects with
CommandBuilder-generated update logic for each, and uses the DataAdapter
objects to update the Orders and Order Details tables in Northwind.
The client-side code contains two event handlers and one configuration file:
Form.Load
Sets up the example by calling the LoadOrders( ) method in the remote object to
populate a DataSet. The default view of the Orders table is bound to the data grid
on the form.
Update Button.Click


Calls the UpdateOrders( ) method in the remote object passing a DataSet
containing changes made to the DataSet since the form was loaded or since the last
time the UpdateOrders( ) method was called.
Client-side configuration file
Contains parameters used to register the remote class and channel on the client so
that the remote class can be instantiated by the client.
The C# server-side code that registers the remoteable class for activation is shown in
Example 4-27
.
Example 4-27. File: NorthwindServerCS\MainForm.cs
// Namespaces, variables, and constants
using System;
using System.Configuration;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

using ADOCookbookCS.NorthwindRemoteCS;

private bool isStarted = false;

// . . .

private void startServerButton_Click(object sender, System.EventArgs e)
{
if (!isStarted)
{
// config file
RemotingConfiguration.Configure(

"NorthwindServerCS.exe.config");

serverResultTextBox.Text += "Remote server started." +
Environment.NewLine +
" ApplicationName = " +
RemotingConfiguration.ApplicationName +
Environment.NewLine +
" ApplicationId = " +
RemotingConfiguration.ApplicationId +
Environment.NewLine +
" ProcessId = " +
RemotingConfiguration.ProcessId;

isStarted = true;
}
else
{
serverResultTextBox.Text +=
"Remote Server already started." + Environment.NewLine;
}
}
Example 4-28. File: NorthwindServerCS\NorthwindServerCS.exe.config
<configuration>
<system.runtime.remoting>
<application name="RemoteClass (WellKnownServiceType)">
<service>
<wellknown
mode="SingleCall"
type="ADOCookbookCS.NorthwindRemoteCS.RemoteClass,
NorthwindRemoteCS"

objectUri="RemoteClass">
</wellknown>
</service>
<channels>
<channel ref="tcp server" port="1234" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
The C# remoteable class code is shown in Example 4-29
.
Example 4-29. File: NorthwindRemoteCS\NorthwindRemoteCS.cs
// Namespaces, variables, and constants
using System;
using System.Data;
using System.Data.SqlClient;

// . . .

namespace ADOCookbookCS.NorthwindRemoteCS
{
/// <summary>
/// Summary description for NorthwindRemote
/// </summary>
public class RemoteClass : MarshalByRefObject
{
public const String SQL_CONNECTIONSTRING =
"Data Source=(local);Integrated security=SSPI;" +
"Initial Catalog=Northwind;";


// Table name constants
private const String ORDERS_TABLE = "Orders";
private const String ORDERDETAILS_TABLE = "OrderDetails";

// Relation name constants
private const String ORDERS_ORDERDETAILS_RELATION =
"Orders_OrderDetails_Relation";

// Field name constants
private const String ORDERID_FIELD = "OrderID";

public DataSet LoadOrders( )
{
DataSet ds = new DataSet( );

SqlDataAdapter da;

// Fill the Order table and add it to the DataSet.
da = new SqlDataAdapter("SELECT * FROM Orders",
SQL_CONNECTIONSTRING);
DataTable orderTable = new DataTable(ORDERS_TABLE);
da.FillSchema(orderTable, SchemaType.Source);
da.Fill(orderTable);
ds.Tables.Add(orderTable);

// Fill the OrderDetails table and add it to the DataSet.
da = new SqlDataAdapter("SELECT * FROM [Order Details]",
SQL_CONNECTIONSTRING);
DataTable orderDetailTable =
new DataTable(ORDERDETAILS_TABLE);

da.FillSchema(orderDetailTable, SchemaType.Source);
da.Fill(orderDetailTable);
ds.Tables.Add(orderDetailTable);

// Create a relation between the tables.
ds.Relations.Add(ORDERS_ORDERDETAILS_RELATION,
ds.Tables[ORDERS_TABLE].Columns[ORDERID_FIELD],
ds.Tables[ORDERDETAILS_TABLE].
Columns[ORDERID_FIELD], true);

return ds;
}

public bool UpdateOrders(DataSet ds)
{
// Create the DataAdapters for order and order details
// tables.
SqlDataAdapter daOrders =
new SqlDataAdapter("SELECT * FROM Orders",
SQL_CONNECTIONSTRING);
SqlDataAdapter daOrderDetails = new
SqlDataAdapter("SELECT * FROM [Order Details]",
SQL_CONNECTIONSTRING);

// Use CommandBuilder to generate update logic.
SqlCommandBuilder cbOrders =
new SqlCommandBuilder(daOrders);
SqlCommandBuilder cbOrderDetails =
new SqlCommandBuilder(daOrderDetails);


// Update parent and child records.
daOrderDetails.Update(
ds.Tables[ORDERDETAILS_TABLE].Select(null, null,
DataViewRowState.Deleted));
daOrders.Update(ds.Tables[ORDERS_TABLE].Select(
null, null, DataViewRowState.Deleted));
daOrders.Update(ds.Tables[ORDERS_TABLE].Select(null,
null, DataViewRowState.ModifiedCurrent));
daOrders.Update(ds.Tables[ORDERS_TABLE].Select(null,

×