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

/// <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(40NOT NULL ,
    SupplierID 
int NULL ,
    CategoryID 
int NULL ,
    QuantityPerUnit 
nvarchar(20NULL ,
    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(20NOT NULL ,
    FirstName 
nvarchar(10NOT NULL ,
    Title 
nvarchar(30NULL ,
    TitleOfCourtesy 
nvarchar(25NULL ,
    BirthDate 
datetime NULL ,
    HireDate 
datetime NULL ,
    Address 
nvarchar(60NULL ,
    City 
nvarchar(15NULL ,
    Region 
nvarchar(15NULL ,
    PostalCode 
nvarchar(10NULL ,
    Country 
nvarchar(15NULL ,
    HomePhone 
nvarchar(24NULL ,
    Extension 
nvarchar(4NULL ,
    Photo 
image NULL ,
    Notes 
ntext NULL ,
    ReportsTo 
int NULL ,
    PhotoPath 
nvarchar(255NULL
)
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 语句的代码,其实并不难。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值