programming4us
programming4us
MOBILE

Synchronizing Mobile Data : Using RDA

9/20/2010 9:44:40 AM
Once you have completed configuring the components, you can develop and test your RDA and Merge Replication applications. We begin with RDA, the easier to administer but less capable of the two.

1. RDA Capabilities and Overhead

RDA enables a SQL Server CE application to do the following:

  • Retrieve data and schemas from a SQL Server database into a SQL Server CE database on a device

  • Add to, remove, or modify that data at the device and have SQL Server CE track those changes

  • Have SQL Server CE submit the changed data to the SQL Server database and receive any exceptions resulting from failed updates on the server

  • Submit SQL statements directly from the .NET Compact Framework application to a SQL Server database

RDA is simpler than Merge Replication, but it requires that you write more code, both C# code and SQL code. It also requires that you use an ADO.NET class SqlCeRemoteDataAccess class. when we accessed a SQL Server database: the

RDA uses a concurrency model that the online documentation calls optimistic concurrency. The meaning of optimistic concurrency in RDA is different from the meaning known by many veteran SQL Server programmers. In RDA, optimistic concurrency means the following activities take place.

  1. Pull data from the server to the device.

  2. Modify the data on the device.

  3. Submit data changes to the server.

  4. The server applies the changes even if the data on the server has been modified since it was pulled to the device.

So, you need to adopt a new mindset if you are used to optimistic concurrency meaning the following.

  1. Retrieve data into the application.

  2. Modify data within the application.

  3. Submit data changes to the server.

  4. The server does not apply the changes if the data on the server has been modified since it was read by the application.

For instance, the following RDA scenario causes one update to overlay another.

08:00Client A pulls data from the server.
08:00Client B pulls data from the server.
12:00Client A updates row X on device A.
12:00Client B updates row X on device B.
18:00Client A pushes updates to the server.
19:00Client B pushes updates to the server.

Client B’s update overlays Client A’s update. No warning, error, exception, or conflict occurs.

The following change to the scenario causes B’s update to fail.

12:00Client A deletes row X.

In the new scenario, there is no row X on the server at 19:00, and B’s update fails. When this failure occurs, RDA logs the failure in the local database. It is up to the client application to make whatever changes to local data that it feels are appropriate and to notify the user of the failure.

2. Programming for RDA

The primary ADO.NET class for RDA programming is SqlCeRemoteDataAccess. This class has three methods, corresponding to the three capabilities mentioned earlier (SubmitSQL, Pull, and Push), plus additional methods inherited from its base classes. It also has a set of properties for providing connection information. Table 1 lists the main methods and properties of the SqlCeRemoteDataAccess class.

Table 1. Methods and Properties of the SqlCeRemoteDataAccess Class
NameComment
Methods
PullSubmits a SELECT statement to a SQL Server database. Creates a table and indexes in a SQL Server CE database to hold the selected data. Retrieves the selected rows and inserts them into the table. Initiates tracking of changes made to the selected data
PushSubmits changes made to previously pulled data back to the SQL Server. Receives errors from the SQL Server and stores them in an application-specified error table
SubmitSQLSubmits SQL statements to a SQL Server
Properties
InternetLogonInternet username
InternetPasswordInternet user password
InternetProxyLogonProxy username
InternetProxyPasswordProxy password
InternetProxyServerProxy server name
InternetURLURL of the sscesa20.dll file at a Web site (i.e., the virtual directory specified in the Virtual Directory Alias and Content Folder dialog box of the Virtual Directory Creation Wizard
LocalConnectionStringConnection string for the SQL Server CE database

2.1. Pulling Data

The Pull method submits a SQL SELECT statement to the SQL Server for processing. The method creates the table to hold the returned rows; that table must not already exist. Some of the information the Pull method needs is specified by setting properties before invoking the method; some is supplied through the parameters, which are shown in Table 2.

Table 2. Parameters of the Pull Method
ParameterComment
localTableNameName of the SQL Server CE table to be created to receive the output of the SELECT statement
sqlSelectStringThe SELECT statement
oledbConnectionStringThe connection string used to access the SQL Server database
trackOptionsAn enumerated indicator specifying whether changes to the data in the table should be tracked so that they can be subsequently pushed back to the SQL Server. Also specifies whether indexes should be created on the local table
errorTableThe name of a table to be created in the local database that holds errors returned by subsequent pushes

For example, the code shown in Listing 8.1 pulls information from the Northwind Categories table and stores it in a newly created table that is also to be named Categories. Listings 1 through 5 show the code that you can find in the RDA project at the book’s Web site.

Listing 1. An RDA Pull
//  The database file
private string strDBFile = @"My Documents\Northwind.sdf";

// The local connection string
private string strConnLocal =
"Data Source=" + @"My Documents\Northwind.sdf";

// The remote connection string
private string strConnRemote = "Provider=sqloledb; "
+ "Data Source=Snowden; "
+ "Initial Catalog=Northwind; "
+ "Integrated Security=SSPI;";

// The URL
private string strURL =
"http://207.202.168.30/YaoDurantRDA/sscesa20.dll";


private void mitemPull_Click(object sender, EventArgs e)
{
// Create an RDA object.
SqlCeRemoteDataAccess rdaNW = new SqlCeRemoteDataAccess();

try
{
// Have RDA:
// Create local tables named Categories and
// ErrorCategories.
// Connect to the remote server and submit the
// SELECT statement.
// Place the results in the local Categories table.
rdaNW.LocalConnectionString = strConnLocal;
rdaNW.InternetUrl = strURL;
rdaNW.InternetLogin = "";
rdaNW.InternetPassword = "";
rdaNW.Pull("Categories",
"SELECT CategoryID, CategoryName " +
" FROM Categories",
strConnRemote,
RdaTrackOption.TrackingOnWithIndexes,
"ErrorCategories");
}
catch(SqlCeException exSQL)
{
HandleSQLException(exSQL);
}
finally
{
rdaNW.Dispose();
}


2.2. Fixing the IDENTITY Property

When you pull a table from SQL Server down to your device using RDA, the schema of that table is brought with the data so that the table can be created on the device. That schema might be incorrect regarding the IDENTITY property. If the SQL Server table has an IDENTITY property column, the new SQL Server CE table also has that column designated as an IDENTITY property column, but its seed and increment are always set to (1,1). You must initially correct them to the values you want, as shown in Listing 2.

Listing 2. Setting the IDENTITY Property Column’s Seed Value
//  The IDENTITY property seed value of the new table
// is at 1, even after the retrieved rows have
// been added to the table. "Fix" it.
SqlCeConnection connLocal = new SqlCeConnection(strConnLocal);
connLocal.Open();

SqlCeCommand cmndLocal = new SqlCeCommand();
int intMaxCategoryID;
try
{
cmndLocal.Connection = connLocal;
// Retrieve the highest CategoryID in the table.
cmndLocal.CommandText =
"SELECT max(CategoryID) FROM Categories";
string strMaxCategoryID =
cmndLocal.ExecuteScalar().ToString();
intMaxCategoryID = int.Parse(strMaxCategoryID);

// Set the seed one higher.
cmndLocal.CommandText =
"ALTER TABLE Categories " +
"ALTER COLUMN CategoryID IDENTITY (" +
(intMaxCategoryID + 1).ToString() + ",1)";
cmndLocal.ExecuteNonQuery();
}
catch( SqlCeException exSQL )
{
HandleSQLException(exSQL);
}
finally
{
connLocal.Close();
}


Be aware that the auto-generated CategoryID value of any rows that you insert into the local Categories table is always overridden with a new value when those rows are pushed to the host server.

2.3. Viewing the Pulled Schema

If you use RDA to retrieve data from the desktop and you plan to propagate local changes to that data back to the desktop server, you must specify one of the change-tracking enumerations in the fourth parameter when you pull the data.

Two of the tracking options also specify that indexes are to be created on the local table. The TrackingOnWithIndexes option adds yet one more index to your table. Do your own performance testing to determine whether your application benefits from the indexes. Using either tracking option adds the two extra columns shown in Figure 5 to your database. Using the TrackingOnWithIndexes option adds the extra index also shown in Figure 5.

Figure 5. A Table Pulled with Tracking and Indexes


2.4. Modifying Pulled Data Locally

The connection to SQL Server is open only while the data is being pulled. When the data has been transferred to the SQL Server CE data table, the SQL Server connection is closed. Once you have pulled the data and, if necessary, altered the IDENTITY property.

Listing 3. Modifying Pulled Data at the Device
private void mitemUpdate_Click(object sender, EventArgs e)
{
SqlCeConnection connLocal =
new SqlCeConnection(strConnLocal);
connLocal.Open();

SqlCeCommand cmndLocal = new SqlCeCommand();
try
{
cmndLocal.Connection = connLocal;
cmndLocal.CommandText =
"UPDATE Categories " +
" SET CategoryName = 'new Name' " +
" WHERE CategoryID = 2";
cmndLocal.ExecuteNonQuery();

cmndLocal.CommandText =
"DELETE Categories WHERE CategoryID = 3";
cmndLocal.ExecuteNonQuery();

cmndLocal.CommandText =
"INSERT Categories (CategoryName) " +
" VALUES ('new Category I') ";
cmndLocal.ExecuteNonQuery();
}
catch( SqlCeException exSQL )
{
HandleSQLException(exSQL);
}
finally
{
cmndLocal.Dispose();
connLocal.Close();
}
}


Figure 6 shows the Categories data after modification. The row for CategoryID = 3 has been deleted, the row for CategoryID = 2 has been modified, and a new row with CategoryID = 10 has been added.

Figure 6. The Categories Table after Updates


The inserted and modified rows are marked in the s_Operation column; the deleted row is represented in the MSysRDATombstone table.

2.5. Pushing Data

To propagate the table’s changes back to the desktop SQL Server, you use the Push method of the SqlCeRemoteDataAccess class. This is shown in Listing 4.

Listing 4. An RDA Push
private void mitemPush_Click(object sender, EventArgs e)
{
// Create an RDA object.
SqlCeRemoteDataAccess rdaNW =
new SqlCeRemoteDataAccess();
try
{
// Have RDA:
// Create local tables named Categories and
// ErrorCategories.
// Connect to the remote server and submit
// the changes.
rdaNW.LocalConnectionString = strConnLocal;
rdaNW.InternetUrl = strURL;
rdaNW.InternetLogin = "";
rdaNW.InternetPassword = "";
rdaNW.Push("Categories", strConnRemote);
}
catch( SqlCeException exSQL )
{
HandleSQLException(exSQL);
}
finally
{
rdaNW.Dispose();
}
}


After the Push method completes, you can detect the rows that failed to update at the server due to concurrency conflicts by accessing the local table that was specified as a Pull method parameter. In our case, this was the ErrorCategories table, shown in Figure 10, specified as the last parameter in the following code snippet extracted from Listing 1.

rdaNW.Pull("Categories",
"SELECT CategoryID, CategoryName " +
" FROM Categories",
strConnRemote,
RdaTrackOption.TrackingOnWithIndexes,
"ErrorCategories");

Figure 7 shows the contents of the Categories table that we pulled to the local database.

Figure 7. Remote Data before the Push


When we push the changes back to the SQL Server database, using the code in Listing 8.4, the following activities occur.

  1. The modified row from our local database is modified on the server.

  2. The deleted row in our local database fails to delete because of a foreign key violation; there are some Confections products in the remote database, so the category cannot be deleted.

  3. The inserted row from our local database fails to insert because a CategoryId = 10 row already exists in the remote database. Perhaps some other user added this row; perhaps we added it with a SubmitSQL method call.

This can be verified by viewing the contents of the Categories table on the server after the push has completed, as shown in Figure 8.

Figure 8. Remote Data after the Push


When the Push method executed, it raised the exception shown in Figure 9. As a result of the exception, the rows shown in Figure 10 were added to the SQL Server CE ErrorCategories table.

Figure 9. The Push Method Error Message


Figure 10. The ErrorCategories Table after the Push


There is no automatic conflict resolution in RDA. You must examine the failed rows placed in the error table and decide what changes to make to the data on your device as a result of the failed server updates.

2.6. The SubmitSQL Method

The SubmitSQL method is pretty self-explanatory. It bypasses the SQL Server CE database completely and simply submits a SQL statement to the SQL Server for processing. This method is used for submitting updates to the server. (If you submit a SELECT statement, no exception will be thrown, but you will not accomplish anything.) For example, Listing 5 shows the code used to insert a row into the remote Categories table; in fact, it was one of the rows that caused our subsequent push to fail.

Listing 5. Executing the SubmitSQL Method
private void mitemSubmitSQL_Click(object sender, EventArgs e)
{
// Create an RDA object.
SqlCeRemoteDataAccess rdaNW = new SqlCeRemoteDataAccess();
try
{
// Have RDA:
// Create local tables named Categories and
// ErrorCategories.
// Connect to the remote server and submit
// the changes.
rdaNW.LocalConnectionString = strConnLocal;
rdaNW.InternetUrl = strURL;
rdaNW.InternetLogin = "";
rdaNW.InternetPassword = "";
rdaNW.SubmitSql(
"INSERT Categories (CategoryName, Description)" +
"VALUES ('New Category II', 'From SubmitSQL')",
strConnRemote);
}
catch( SqlCeException exSQL )
{
HandleSQLException(exSQL);
}
finally
{
rdaNW.Dispose();
}
}


As is the case with the Push and Pull methods, the SubmitSQL method requires that you set property values with the information appropriate to your Web site configuration and that you correctly code your SQL statements. Once you have done that, transferring the data is a matter of a single method call.

As we are about to see, this emphasis on providing connection information through property values and the need to understand database technology continues into Merge Replication. But when you understand how your application connects to the server and how to request data from the server, you will be able to transfer data with even less code than RDA requires.

Other  
 
Video
PS4 game trailer XBox One game trailer
WiiU game trailer 3ds game trailer
Top 10 Video Game
-   World of Warcraft | Patch 6.2 Survival Guide
-   Whispering Willows | Launch Trailer
-   Tales from the Borderlands | Episode 3 'Catch a Ride' Trailer
-   Batman: Arkham Knight [PS4/XOne/PC] Launch Trailer
-   Tom Clancy's Ghost Recon: Wildlands | E3 Tralier
-   Blade & Soul [PC] Follow My Blade Trailer
-   Heroes Charge - Trio VW + EB + SIL vs WC FD CW EB Com
-   PlanetSide 2 | PS4 Launch Trailer 'Redefining Massive Warfare
-   DRIVECLUB | PS4 All-Action Trailer
-   Wave of Darkness [PC] Early Access Trailer
-   Tony Hawk's Pro Skater 5 | "THPS is Back" Trailer
-   Poly Bridge [PC] Trailer
-   Persona 5 | Leaked Trailer 2 w/ Dancing All Night
-   Evolve [PS4/XOne/PC] Lennox Gameplay Trailer
-   Lexus Slide | Real, rideable hoverboard
Game of War | Kate Upton Commercial
programming4us
 
 
programming4us