一、场景描述
在智能设备(Smart Device)应用程序和智能客户端(Smart Client)应用程序的部署阶段,我们需要对离线数据进行初始化,即将后台数据库服务器中的一些数据,导入到离线数据库中。通常采用两种方式对离线数据进行初始化,第一种是在程序第一次运行时,通过数据同步的方式,把数据从后台下载下来;第二种是将预先准备好的离线数据随应用程序一起部署。
对于 SQL Server Compact Edition (SQL CE 3.1) 数据库,第一种方式通常可以利用 Remote Data Access (RDA), Merge Replication, Sync Services for ADO.NET (SQL CE 3.5 中新增) 或者自己实现基于 Web Service 的数据同步机制来实现。RDA 和 Merge Replication 最大的缺点是只能连到 SQL Server 数据库,如果 SQL CE 需要跟 Oracle 和DB2等数据库进行数据同步,需要 SQL Server 做“中介”。另外,RDA 没有冲突处理机制,并且每次必须重新下载全部数据;Merge Replication 配置太繁琐了。Sync Services for ADO.NET 目前还在 beta 阶段,beta1 还不支持智能设备应用程序,只支持桌面应用程序。Orcas beta2 刚刚发布,目前还没有下载完毕,不知道有没有性能方面的提升和增加对智能设备应用程序的支持。暂时先对 Sync Services for ADO.NET 保留意见,等我用上 beta2 了再详细介绍。自己实现基于 Web Service 的数据同步机制需要考虑大数据量如何分批次传输和性能问题。总的来说,第一种方式的实现途径很多,如果初始化数据量比较大,并且客户端数量比较多的话,那么将有可能带来漫长的部署过程和一笔巨大的无线网络流量的费用。
第二种方式可以利用 SQL CE 3.1 对桌面应用程序的支持,预先将 SQL Server, Oracle, DB2, MySQL 等等各种数据库的数据导入到 SQL CE 中,然后通过 ActiveSync 批量将 SQL CE 的数据库文件(*.sdf)拷贝到设备或机器上。以后客户端再通过 Web Service 的方式下载新增/修改/删除的数据来更新本地的离线数据。这样可以节约大量的部署时间和网络通信成本。
当然并不是第二种方式一定比第一种方式好,这个看具体的实施环境。本文主要介绍的是第二种方式。
二、技术选择
既然 SQL CE 3.1 支持桌面应用程序,那么我们可以通过三种方式来准备离线数据:第一,利用 RDA 数据同步;第二,利用 Merge Replication 数据同步;第三,用 ADO.NET 直接从读写数据。第一和第二种方式需要额外的安装和配置,而且只支持 SQL Server 数据库。如果非要在第一和第二种方式中选择的话,我会选择 RDA,因为它配置工作量更少,性能更好,更加灵活。本文选择第三种方式,因为它离两个数据库的距离最近,而且支持多种数据库。
三、实现原理
数据导入程序实现起来很简单,不过需要考虑性能。从源数据库读取数据要考虑速度和内存冲击,可以采用 DataSet 或者 DataReader,毫无疑问我们选择 DataReader。将数据写入 SQL CE,通常大家会想到编写一个 SqlCeCommand,然后给 SqlCeCommand 的 CommandText 属性赋上 Insert SQL 语句“insert into Products values(@ProductID, @ProductName)”,接着一边读取数据,一边给参数赋值并写入 SQL CE 数据库中……大家冷落了一个叫 SqlCeResultSet 的对象,它是 SQL Mobile 增加的数据访问对象。SqlCeResultSet 提供了一个功能的组合:DataSet 的可更新性和可滚动性以及与 SqlCeDataReader 类似的性能。SqlCeResultSet 类继承了 SqlCeDataReader 类,因此它拥有 SqlCeDataReader 类所有的特性。利用 SqlCeResultSet 可以实现高性能的数据读取和写入。
四、代码和分析
///<summary>
///将源数据库表的数据复制到SQLServerCompactEdition数据库的表中。
///</summary>
///<paramname="srcConnection">源数据库连接接对象。</param>
///<paramname="destConnection">目标SQLServerCompactEdition数据库连接对象。</param>
///<paramname="queryString">源数据的查询语句。</param>
///<paramname="destTableName">目标数据库表名称。</param>
///<remarks>本方法假设目标SQLServerCompactEdition数据库的表已经存在。</remarks>
publicstaticvoidCopyTable(
IDbConnectionsrcConnection,
SqlCeConnectiondestConnection,
stringqueryString,
stringdestTableName)
{
IDbCommandsrcCommand=srcConnection.CreateCommand();
srcCommand.CommandText=queryString;
SqlCeCommanddestCommand=destConnection.CreateCommand();
destCommand.CommandType=CommandType.TableDirect;//基于表的访问,性能更好
destCommand.CommandText=destTableName;
try
{
IDataReadersrcReader=srcCommand.ExecuteReader();
SqlCeResultSetresultSet=destCommand.ExecuteResultSet(
ResultSetOptions.Sensitive|//检测对数据源所做的更改
ResultSetOptions.Scrollable|//可以向前或向后滚动
ResultSetOptions.Updatable);//允许更新数据
object[]values;
SqlCeUpdatableRecordrecord;
while(srcReader.Read())
{
//从源数据库表读取记录
values=newobject[srcReader.FieldCount];
srcReader.GetValues(values);
//把记录写入到目标数据库表
record=resultSet.CreateRecord();
record.SetValues(values);
resultSet.Insert(record);
}
srcReader.Close();
resultSet.Close();
}
catch(Exceptionex)
{
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 函数:
//创建源SQLServer数据库连接对象
stringsrcConnString="DataSource=(local);InitialCatalog=Northwind;IntegratedSecurity=True";
SqlConnectionsrcConnection=newSqlConnection(srcConnString);
//创建目标SQLServerCompactEdition数据库连接对象
stringdestConnString=@"DataSource=C:\Northwind.sdf";
SqlCeConnectiondestConnection=newSqlCeConnection(destConnString);
VerifyDatabaseExists(destConnString); //创建数据库结构
srcConnection.Open();
destConnection.Open();
//复制数据
CopyTable(srcConnection,destConnection,"SELECT*FROMProducts","Products");
CopyTable(srcConnection,destConnection,"SELECT*FROMEmployees","Employees");
srcConnection.Close();
destConnection.Close();
五、创建数据库结构
上面说到在使用 CopyTable 函数之前 SQL CE 数据库必须存在并且表结构都创建好。我们现在就来编写创建数据库结构的代码。首先创建一个名为 DbSchema.sql 的文件,并编写 Northwind 数据库中的 Products 和 Employees 表的创建脚本:
CREATETABLEProducts(
ProductIDintNOTNULLCONSTRAINTPK_ProductsPRIMARYKEY,
ProductNamenvarchar(40)NOTNULL,
SupplierIDintNULL,
CategoryIDintNULL,
QuantityPerUnitnvarchar(20)NULL,
UnitPricemoneyNULL,
UnitsInStocksmallintNULL,
UnitsOnOrdersmallintNULL,
ReorderLevelsmallintNULL,
DiscontinuedbitNOTNULL
)
GO
CREATETABLEEmployees(
EmployeeIDintNOTNULLCONSTRAINTPK_EmployeesPRIMARYKEY,
LastNamenvarchar(20)NOTNULL,
FirstNamenvarchar(10)NOTNULL,
Titlenvarchar(30)NULL,
TitleOfCourtesynvarchar(25)NULL,
BirthDatedatetimeNULL,
HireDatedatetimeNULL,
Addressnvarchar(60)NULL,
Citynvarchar(15)NULL,
Regionnvarchar(15)NULL,
PostalCodenvarchar(10)NULL,
Countrynvarchar(15)NULL,
HomePhonenvarchar(24)NULL,
Extensionnvarchar(4)NULL,
PhotoimageNULL,
NotesntextNULL,
ReportsTointNULL,
PhotoPathnvarchar(255)NULL
)
GO
这段 SQL 语句不能直接在 SQL CE 上执行的,我们需要进行一些字符串的处理。现在将该文件添加到 Visual Studio 2005 的项目资源中。
并添加执行这段 SQL 创建数据库表结构的方法:
publicstaticvoidVerifyDatabaseExists(stringconnectionString)
{
using(SqlCeConnectionconnection=newSqlCeConnection(connectionString))
{
if(!File.Exists(connection.Database))
{
using(SqlCeEngineengine=newSqlCeEngine(connection.ConnectionString))
{
engine.CreateDatabase();
string[]commands=Properties.Resources.DbSchema.Split(
newstring[]{"GO"},StringSplitOptions.RemoveEmptyEntries);
SqlCeCommandcommand=newSqlCeCommand();
command.Connection=connection;
connection.Open();
for(inti=0;i<commands.Length;i++)
{
command.CommandText=commands[i];
command.ExecuteNonQuery();
}
}
}
}
}
六、总结
性能测试的结果会因为环境的不同而有一些出入,我想留给大家去做会更有意义。不过我相信这是当前性能比较好的向 SQL CE 导入数据的方法之一。目前需要预先创建好 SQL CE 的表结构是美中不足的地方,我会在后续文章中实现一个自动根据查询结果生成创建 SQL CE 表结构的 SQL 语句的代码,其实并不难。
参考:
ADO.NET Generic Copy Table Data Function
Creating your SQL Server Compact Edition database and schema in code
示例代码下载:sqlce_data_import.rar
作者:黎波
博客:http://upto.cnblogs.com/
日期:2007年7月29日
分享到:
相关推荐
用sqlserver 创建.sdf数据库文件其实很简单 步骤如下: (1)打开sqlserver2008 (2)服务器类型选项中选择sqlserver compact edition (3)数据库文件选项选择新建数据库到新建数据库页面 (4)填写数据库名和密码确认就ok了
3. 数据导入导出:将数据从其他格式导入SQL Server,或将SQL Server数据导出到其他格式。 4. 备份与恢复:定期备份数据库以防止数据丢失,当需要时进行恢复操作。 5. 性能监控:通过工具监控数据库性能,识别瓶颈并...
综上所述,这个程序利用C#语言,实现了SQL Server 2000数据库到适用于PDA的SQL Server Compact Edition数据库的转换,确保了数据的一致性,从而方便用户在移动设备上继续使用和访问原有的数据库内容。对于开发者来说...
这可能涉及到读取PDA数据库中的记录,通过网络连接将数据传输到服务器,然后在SQL Server上进行相应的插入、更新操作。反之亦然,服务器端的数据变化也需要同步到PDA。这个过程可能需要用到触发器、轮询或其他同步...
4. **数据导入导出**:支持将数据从其他数据源导入到 SQL Server Compact,或者将数据导出到其他格式,如 CSV 或 Excel。这对于数据迁移或集成提供了便利。 5. **版本兼容性**:SqlCe40Toolbox 是专为 SQL Server ...
工具会执行相应的查询,将数据导入到新的SQLCE3.5数据库中,生成.SDF文件。这种方式能够确保数据的安全性和完整性,同时也比手动迁移快得多。 在转换过程中,SQLCEQuery可能需要处理一些关键的转换问题,例如数据...
综上所述,"3SQLCESample"是一个实用的示例项目,它演示了如何在C#环境中利用Visual Studio 2008和ADO.NET技术,将Access数据库转换为SQL Server Compact Edition数据库,对于学习数据库迁移和C#数据库编程的初学者...
标题“SQL转换为SQLCE”涉及的是将标准的SQL(结构化查询语言)数据库转换成SQL Server Compact Edition(SQLCE)的过程。SQLCE是一个轻量级、嵌入式数据库引擎,适用于移动设备和桌面应用程序,它不需要单独的...
在本示例中,我们将探讨如何使用C#编程语言操作SQL Server Compact Edition(SQL CE)数据库,并将数据导入到SQL Server数据库,以及导出为Excel文件。SQL CE是一个轻量级、嵌入式的关系型数据库管理系统,适合用于...
SQL CE(SQL Server Compact Edition)是微软的一款轻量级数据库,适合移动和嵌入式设备。工具对SQL CE的支持使得开发者能在资源有限的环境下实现数据库管理。 最后,ORACLE作为全球最大的数据库供应商,其数据库...
5. 导入导出数据:支持将数据从其他格式(如CSV、Excel)导入到SqlCE数据库,或者将数据库中的数据导出到这些格式。 6. 错误处理与日志记录:良好的错误处理机制可以及时捕获并报告数据库操作过程中出现的问题,...
8. SQL Server Compact Edition:一个轻量级的、嵌入式数据库引擎,适用于桌面和移动应用。 9. Analysis Services和Reporting Services:提供商业智能和报表服务,用于数据挖掘和复杂数据分析。 在压缩包中的...
SQLCE SDF 数据文件查看器CompactView_1.4.2.0是一款专门设计用于查看Windows CE(wince)系统中使用到的SQL Server Compact Edition(SQLCE)数据文件的应用程序。这款工具允许用户轻松地浏览和分析存储在SDF文件中...
SQLCE(SQL Server Compact Edition)是一款轻量级的数据库管理系统,由微软开发,适用于桌面和移动应用程序。它提供了与标准SQL Server类似的功能,但体积更小,无需单独的服务器进程,可以直接嵌入到应用程序中。...
SDF文件,全称为Structured Data File,通常与Microsoft SQL Server Compact Edition相关联,是一种轻量级的数据库格式,广泛应用于移动设备和嵌入式系统中。尽管小巧,但SDF文件依然具备了SQL数据库的核心功能,如...
5. **导出导入**:支持将数据导出为 CSV 或其他格式,或者从外部文件导入数据。 6. **性能分析**:通过执行计划和性能计数器来分析查询性能。 7. **脚本编写**:创建和管理 SQL 脚本,便于重复执行或自动化任务。 *...
在Windows CE(简称WinCE)平台上进行开发时,SQL Server Compact Edition(SQL CE)是一个非常重要的数据库管理系统。它为移动设备和嵌入式系统提供了轻量级、离线数据库解决方案。在本文中,我们将深入探讨如何在...
接下来,将Access中的数据逐条导入到SQL CE中,可能需要使用SqlCeCommand对象执行INSERT语句。 在这个过程中,还需要处理一些潜在的问题,例如数据类型不兼容、字段长度限制等。Access和SQL CE的数据类型有所不同,...
数据存储方面,由于这是一个简单的系统,很可能采用了关系型数据库如SQL Server Compact Edition或SQLite。在C#中,可以使用ADO.NET进行数据库操作,通过 SqlConnection、SqlCommand、SqlDataAdapter等类与数据库...