您的位置:首页 > 移动开发

实现 手机端和服务器端的数据同步技术

2009-07-15 20:11 561 查看
/// <summary>
/// 将源数据库表的数据复制到 SQL Server Compact Edition 数据库的表中。
/// </summary>
/// <param name="srcConnection">源数据库连接接对象。</param>
/// <param name="destConnection">目标 SQL Server Compact Edition 数据库连接对象。</param>
/// <param name="queryString">源数据的查询语句。</param>
/// <param name="destTableName">目标数据库表名称。</param>
/// <remarks>本方法假设目标 SQL Server Compact Edition 数据库的表已经存在。</remarks>
public static void CopyTable(
IDbConnection srcConnection,
SqlCeConnection destConnection,
string queryString,
string destTableName)
{
IDbCommand srcCommand = srcConnection.CreateCommand();
srcCommand.CommandText = queryString;

SqlCeCommand destCommand = destConnection.CreateCommand();
destCommand.CommandType = CommandType.TableDirect; //基于表的访问,性能更好
destCommand.CommandText = destTableName;
try
{
IDataReader srcReader = srcCommand.ExecuteReader();

SqlCeResultSet resultSet = destCommand.ExecuteResultSet(
ResultSetOptions.Sensitive | //检测对数据源所做的更改
ResultSetOptions.Scrollable | //可以向前或向后滚动
ResultSetOptions.Updatable); //允许更新数据

object[] values;
SqlCeUpdatableRecord record;
while (srcReader.Read())
{
// 从源数据库表读取记录
values = new object[srcReader.FieldCount];
srcReader.GetValues(values);

// 把记录写入到目标数据库表
record = resultSet.CreateRecord();
record.SetValues(values);
resultSet.Insert(record);
}

srcReader.Close();
resultSet.Close();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
  由于 CopyTable 函数的源数据库连接参数采用的是 IDbConnection 接口,所以该方法可以支持多种源数据库。代码中还利用 IDataReader.GetValues(object[] values) 和 SqlCeUpdatableRecord.SetValues(object[] values) 更方便的读取和写入数据。

  在使用 CopyTable 函数之前必须预先创建好 SQL CE 数据库的表结构,并且 SQL CE 数据库的表结构必须跟 queryString 参数(select SQL 语句)的查询结果的表结构对应。

  通过下面的代码使用 CopyTable 函数:

// 创建源 SQL Server 数据库连接对象
string srcConnString = "Data Source=(local);Initial Catalog=Northwind;Integrated Security=True";
SqlConnection srcConnection = new SqlConnection(srcConnString);

// 创建目标 SQL Server Compact Edition 数据库连接对象
string destConnString = @"Data Source=C:/Northwind.sdf";
SqlCeConnection destConnection = new SqlCeConnection(destConnString);

VerifyDatabaseExists(destConnString); //创建数据库结构

srcConnection.Open();
destConnection.Open();

// 复制数据
CopyTable(srcConnection, destConnection, "SELECT * FROM Products", "Products");
CopyTable(srcConnection, destConnection, "SELECT * FROM Employees", "Employees"
);

srcConnection.Close();
destConnection.Close();
  五、创建数据库结构

  上面说到在使用 CopyTable 函数之前 SQL CE 数据库必须存在并且表结构都创建好。我们现在就来编写创建数据库结构的代码。首先创建一个名为 DbSchema.sql 的文件,并编写 Northwind 数据库中的 Products 和 Employees 表的创建脚本:

CREATE TABLE Products(
ProductID int NOT NULL CONSTRAINT PK_Products PRIMARY KEY,
ProductName nvarchar(40) NOT NULL,
SupplierID int NULL,
CategoryID int NULL,
QuantityPerUnit nvarchar(20) NULL,
UnitPrice money NULL,
UnitsInStock smallint NULL,
UnitsOnOrder smallint NULL,
ReorderLevel smallint NULL,
Discontinued bit NOT NULL
)
GO
CREATE TABLE Employees(
EmployeeID int NOT NULL CONSTRAINT PK_Employees PRIMARY KEY,
LastName nvarchar(20) NOT NULL,
FirstName nvarchar(10) NOT NULL,
Title nvarchar(30) NULL,
TitleOfCourtesy nvarchar(25) NULL,
BirthDate datetime NULL,
HireDate datetime NULL,
Address nvarchar(60) NULL,
City nvarchar(15) NULL,
Region nvarchar(15) NULL,
PostalCode nvarchar(10) NULL,
Country nvarchar(15) NULL,
HomePhone nvarchar(24) NULL,
Extension nvarchar(4) NULL,
Photo image NULL,
Notes ntext NULL,
ReportsTo int NULL,
PhotoPath nvarchar(255) NULL
)
GO
  这段 SQL 语句不能直接在 SQL CE 上执行的,我们需要进行一些字符串的处理。现在将该文件添加到 Visual Studio 2005 的项目资源中。





  并添加执行这段 SQL 创建数据库表结构的方法:

public static void VerifyDatabaseExists(string connectionString)
{
using (SqlCeConnection connection = new SqlCeConnection(connectionString))
{
if (! File.Exists(connection.Database))
{
using (SqlCeEngine engine = new SqlCeEngine(connection.ConnectionString))
{
engine.CreateDatabase();

string[] commands = Properties.Resources.DbSchema.Split(
new string[] { "GO" }, StringSplitOptions.RemoveEmptyEntries);

SqlCeCommand command = new SqlCeCommand();
command.Connection = connection;
connection.Open();
for (int i = 0; i < commands.Length; i++)
{
command.CommandText = commands[i];
command.ExecuteNonQuery();
}
}
}
}
}
  六、总结

  性能测试的结果会因为环境的不同而有一些出入,我想留给大家去做会更有意义。不过我相信这是当前性能比较好的向 SQL CE 导入数据的方法之一。目前需要预先创建好 SQL CE 的表结构是美中不足的地方,我会在后续文章中实现一个自动根据查询结果生成创建 SQL CE 表结构的 SQL 语句的代码,其实并不难。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: