一、场景描述
在智能设备(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>
/// 将源数据库表的数据复制到 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 语句的代码,其实并不难。
参考:
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日
posted @ 2007-07-29 15:24
黎波 阅读(25986)
评论(136) 编辑 收藏
发表评论
上面的system.data.sqlceclient文件
应该是system.data.sqlserverce文件 是我写错了
未能加载文件或程序集“System.Data.SqlServerCe, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
这是什么原因呢?请指教!
你好
我用直连sqlserver后,.open()的时候出现:
我用的就是下载的例子
未处理 System.Data.SqlClient.SqlException
Message="SqlException"
Class=20
LineNumber=0
Number=11
Procedure="ConnectionRead (recv())."
Server="D0504"
Source=".Net SqlClient Data Provider"
State=0
StackTrace:
at System.Data.SqlClient.SqlConnection.OnError()
at System.Data.SqlClient.SqlInternalConnection.OnError()
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParser.ReadNetlib()
at System.Data.SqlClient.TdsParser.ReadBuffer()
at System.Data.SqlClient.TdsParser.ReadByte()
at System.Data.SqlClient.TdsParser.Run()
at System.Data.SqlClient.TdsParser.Run()
at System.Data.SqlClient.SqlInternalConnection.Login()
at System.Data.SqlClient.SqlInternalConnection.OpenAndLogin()
at System.Data.SqlClient.SqlInternalConnection..ctor()
at System.Data.SqlClient.SqlConnection.Open()
at CopyTableMobileDemo.Form1.button1_Click()
at System.Windows.Forms.Control.OnClick()
at System.Windows.Forms.Button.OnClick()
at System.Windows.Forms.ButtonBase.WnProc()
at System.Windows.Forms.Control._InternalWnProc()
at Microsoft.AGL.Forms.EVL.EnterMainLoop()
at System.Windows.Forms.Application.Run()
at CopyTableMobileDemo.Program.Main()
@songzhaoyi
感觉是SQL语句或存储过程有问题。
楼主您好!
请问我现在不用RDA,但是PDA上还是用SQL MOBILE和总数据库是ORACLE的情况下,什么样的同步解决方案是最好的??
@xuce
最好是用Web Service来实现数据同步,这样就不会依赖于数据库的类型。
实现的方法你可以参考 TaskVision Mobile 版本,它用的是DataSet的方法,比较简单。如果你需要实现复杂的数据同步方案,可以研究这个网站的内容:http://www.syncguru.com/
按照楼主的方法已经将数据导入,估计是数据库当初建立的时候没有设置其大小,默认为128M,现在数据量很大,原数据库的容量大小满足不了要求了,有什么办法能改变原来数据库的大小吗?还请赐教!
我按照您的说法做了,现在导入数据可以超过128M,但数据量超过256M时又出现未指定错误了。我用的连接字符串如下:
string connStr = "Persist Security Info = False; Data Source = TCMT.sdf;Temp File Max Size = 512;Max Database Size =512; Max Buffer Size = 2048";是不是这个串的原因。
如果您有时间的话能不能加我的QQ:277756884,帮我指点一下!
也就是说,用你这个代码访问服务器(PC机)上的SQL的话,服务器要不要开放1433端口呢
这几天都在做这个东西,还是有点小问题,conn.open()的时候,报错:"PlatformNotSupportedException",
连接字 符串"server=220.221.151.100,2433;database=test;uid=sa;pwd=sa;";
程序是在模拟器(模拟器可以上网)上运行上,"220.221.151.100是远程服务器,确定2433(把1433改成了2433)开放,望LZ指点一下,
@hnrpc
我也曾遇到过这种错误信息。如果你的SQL Server服务器是简体中文的操作系统,而你的Pocket PC是非简体中文的操作系统,就会有这个问题。原因是SQL Server数据库的排序规则跟SQL Server CE数据库的不一致,要把它们改成相同就可以了。这可能是SqlClient的bug。
谢谢LZ,换个中文模拟器搞定,最近对移动开发很感兴趣,不知道LZ有没有好的教材书推荐一下
楼主请问:我用VS2005创建一个数据库在模拟器上好用,可是当平台换成WINCE5.0板子的时候,提示"无法找到 PInvoke DLL“sqlceme30.dll”
我该怎么解决呢?谢谢啊.
楼主请问:我用VS2005环境下,创建一个数据库在模拟器上创建成功,可是当平台换成WINCE5.0板子的时候,提示"无法找到 PInvoke DLL“sqlceme30.dll”
我该怎么解决呢?谢谢啊.(我将sqlceme30.dll已经复制到应用程序的目录下).
是不是在WINCE5.0的板子上也需要安装SQL Server Compact Edition,
因为,我直接在板子上手动创建数据库,也创建失败,系统给出的错误提示为
"Failed to initialize the provider. please make sure that SQL Server Compact Edition is properly installed "
谢谢楼主啊
sqlce30.wce5.armv4i.CAB
* sqlce30.dev.ENU.wce5.armv4i.CAB
* sqlce30.repl.wce5.armv4i.CAB
到WinCE5.0中,然后分别安装,都提示安装成功。
但还是不行,请帮帮我,谢谢
从sql2005向sqlCe中导入数据的时候用你说的方法速度确实很快,我现在想从sqlCe或者其他(sql2005、oracle)类型的数据库中将数据导入到sql2005中有没有效率比较高的方法,下面是我做的一个方法(sqlCe数据导入到sql2005),测试后发现速度十分的慢。
/// <summary>
/// 将源数据库表的数据复制到 SQL Server 2005 数据库的表中
/// </summary>
/// <param name="srcConnection">源数据库连接</param>
/// <param name="destConnection">sql server 2005数据库连接(oleDB)</param>
/// <param name="queryString">源数据表的查询语句</param>
/// <param name="destTableName">目标数据表的名称</param>
public void CopyTableToSqlServer(
IDbConnection srcConnection,
OleDbConnection destConnection,
string queryString,
string destTableName
)
{
IDbCommand srcCommand = srcConnection.CreateCommand();
srcCommand.CommandType = CommandType.Text;
srcCommand.CommandText = queryString;
OleDbCommand destCommand = destConnection.CreateCommand();
destCommand.CommandType = CommandType.TableDirect;
destCommand.CommandText = destTableName;
OleDbDataAdapter da = new OleDbDataAdapter(destCommand);
OleDbCommandBuilder builder = new OleDbCommandBuilder(da);
DataSet ds = new DataSet();
da.Fill(ds);
IDataReader srcReader = srcCommand.ExecuteReader();
object[] values;
while(srcReader.Read())
{
//从源数据库中读出一行数据
values = new object[srcReader.FieldCount];
srcReader.GetValues(values);
DataRow row = ds.Tables[0].NewRow();
row.ItemArray = values;
ds.Tables[0].Rows.Add(row);
da.Update(ds.Tables[0]);
}
srcReader.Close();
}
博主您好:
我的程序原来是VS2003(CF1.0)的,用到了RDA(SQL CE2.0与SQL Server2000进行远程同步),调试运行良好。现在我想用VS2005(CF2.0)继续开发,对原来程序升级到CF2.0了,但RDA却又不行了,老是报错,而且每次还报的不一样,有时报:
Error Code:80072F76
Message:内部错误:传输消息中的Http标头信息已坏或缺失。可能是网络传输错误或IIS问题。
Minor Err:28035
但大部分情况下是出错误对话框,说“Unable to create database”,应该是dbEngine.CreateDatabase()时出的错。怎么回事呢?难道是SQL CE2.0在CF2.0下没法用?升级到CF2.0后必须改用SQL Server Mobile(也就是Sqlce3.0)与SQLServer2000同步才行?
附我的RDA代码,在CF1.0下运行一切正常:
if(File.Exists(strDBFile))
{
File.Delete(strDBFile);
}
SqlCeEngine dbEngine = new SqlCeEngine();
dbEngine.LocalConnectionString = strConnLocal;
try
{
dbEngine.CreateDatabase();
}
catch (SqlCeException exSQL)
{
MessageBox.Show("Unable to create database" + exSQL.Errors[0].Message);
}
SqlCeRemoteDataAccess rdaNW = new SqlCeRemoteDataAccess();
try
{
rdaNW.LocalConnectionString = strConnLocal;
rdaNW.InternetUrl = strURL;
rdaNW.InternetLogin = "";
rdaNW.InternetProxyPassword = "";
rdaNW.Pull("patient", "SELECT * FROM patient", strConnRemote, RdaTrackOption.TrackingOnWithIndexes, "ErrorDoctor");
MessageBox.Show("获取数据成功!");
}
catch(SqlCeException exSQL)
{
Errors.ShowErrors(exSQL);
}
finally
{
rdaNW.Dispose();
}
@侯志刚
从错误信息看是SQLCE没有安装好。
你检查一下sqlceme30.dll等文件是否已经存在\Windows目录下,并确认的安装的SQLCE版本的硬件平台是否跟你的板的平台一致。
@guthing
改成这样试一试:
object[] values;
while(srcReader.Read())
{
//从源数据库中读出一行数据
values = new object[srcReader.FieldCount];
srcReader.GetValues(values);
DataRow row = ds.Tables[0].NewRow();
row.ItemArray = values;
ds.Tables[0].Rows.Add(row);
}
da.Update(ds.Tables[0]);
/*慢的原因主要是:DataAdapter.Update() 语句每次执行都要打开和关闭数据库连接,这个操作是最耗资源的,除非你设置了连接池。*/
@wws
我印象中在.NET CF 2.0使用SQLCE 2.0的数据库操作没有问题,没有试过RDA或Merge Replication。
既然你已经升级到.NET CF 2.0了,那就把数据库也升级到SQL Mobile 3.0或SQL Server Compact 3.1吧。
注意你用RDA和Merge Replication的话,IIS服务器上安装的SQL Server Mobile Server Tools应该是对应的版本,旧版本可能会有问题。
感谢楼主帮忙,你说的这种方法我以前试过,由于数据量很大所以没更新之前机器就卡壳了 所以才有以下这种下下策
object[] values;
while(srcReader.Read())
{
//从源数据库中读出一行数据
values = new object[srcReader.FieldCount];
srcReader.GetValues(values);
DataRow row = ds.Tables[0].NewRow();
row.ItemArray = values;
ds.Tables[0].Rows.Add(row);
da.Update(ds.Tables[0]);
}
srcReader.Close();
从sql2005向sqlce中导入数据时是非常的快(就是你介绍的那种做法),但反想操作的时候 速度实在无法忍受。导入数据是个很头痛的问题,有没有别的方法或者别的思路?主要解决速度问题,请楼主帮帮忙...
我想问下,在vs03中,sqlce2.0的情况下,同步数据用什么方式比较好?
RDA是在智能设备中应用,假若我想在桌面端做一个程序,直接在PC端操作将sql server中的数据导到sqlce中呢?
你所讲的是sqlce3.1版本..2.0不支持...那2.0除rda还什么方式?
我的设备是wince4.2系统,不带触摸屏,所以不好在上面开发可以远程操作sql server数据的程序....
@双霜之君
sqlce2.0可以使用自带的RDA和Merge Replication两种数据同步方式,也可以通过WebService实现数据同步,不过要自己处理数据的同步逻辑。
webservice做的话,同步数据的速度快吗?
能不能在pc端操作,不于设备相关呢?
就是说直接在pc端将数据下载下来,然后通过activesync拷贝到设备中??
感谢楼主
我在使用您的这个例子时遇到这样的问题:
sdf数据库已可以按脚本生成,但在将sql server 中的数据导入到 sdf 文件时出现问题,经查看这个问题出在表中有一个自增值的字段id,由于这个字段的数据不能被导入,所以数据导入不成功,这样的情况要怎么解决呢?
谢谢
楼主,您好!!
你上述文章中介绍的第二中数据导入方式的具体开发环境如何搭建,能否将先后顺序详细告知?
为何我安装SSCE31VSTools-ENU.exe文件时,老提示我输入“请插入Microsoft SQL Server 2005 Mobile[CHS] Developer Tools磁盘并单击“确认”按钮。”,我也不知这要输入什么东西,请告知!!
我已搭建这个环境三天了,到现在还不行,急等盼复!!
谢谢!!
@黎波
先谢谢楼主了,我的问题已经解决了,其原因可能是内存不够用了,但是还要感谢楼主的回复。
晕哟,,怎么运行不起呢?
出现:无法加载 DLL“sqlceme30.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。
是不是我的什么软件没有安装?
我的环境是Windows Mobile 5.0
An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
I have opened the remote service of SQL Server by the SQL Server surface area configuration, use local and remote connections( using both TCP/IP and also I have opened the port 1433,)
would u please help me with this error, thanks!
通过楼主的方法,我生成了sdf文件,可在SQL SERVER2005里连接不了,连接就报如下的错误信息,请赐教,谢谢!
===================================
无法连接到 F:\WORK\Dictionary\Dictionary\Dictionary\Data\Data2008.sdf。
===================================
未指定的错误 [ 3505053,3004180,F:\WORK\Dictionary\Dictionary\Dictionary\Data\Data2008.sdf ] (SQL Server Mobile Edition ADO.NET Data Provider)
------------------------------
程序位置:
在 System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
在 System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
在 System.Windows.Forms.Control.Invoke(Delegate method)
在 Microsoft.SqlServer.Management.UI.ConnectionDlg.Connector.ConnectionThreadUser()
黎老师,学生急求....
我连接RF服务器,在将它与IIS进行同步的时候一直出错,不能连接,老师帮忙想个办法啊
我的连接代码如下:
class AppConstant
{
private AppConstant()
{
}
public const string sqlAgent = "http://rb-it-allen/RainBow/sqlcesa30.dll";
public const string rdaOleDbConnstr = "Provider=sqloledb;Persist Security Info=False;;Data Source=RB-IT-AIIEN;Initial Catalog=Northwind;" +
"User Id=sa";
public const string Publisher = "RB-IT-AIIEN";--计算机名
public const string PublisherDatabase = "Northwind";--数据库名
public const string PublisherLogin = "sa";--用户名
public const string PublisherPassword = "";
public const string Publication = "RainBow";--不知道是什么,能帮我讲解下吗?
public const string Subscriber = "BaseData";
public const string localDBPhysicalFile = "\\Program Files\\RBInformsRF\\RainBowCEDB.sdf";
public const string localConnection = @"Data Source= \Program Files\RBInformsRF\RainBowCEDB.sdf";
public const Boolean translateFlag = true;
}
---------------------------------------------
public void BaseDataSynchronize()
{
try
{
// 实例化并配置 SqlCeReplication 对象
SqlCeReplication repl = new SqlCeReplication();
repl.InternetUrl = AppConstant.sqlAgent;
repl.Publisher = AppConstant.Publisher;
repl.PublisherSecurityMode = SecurityType.DBAuthentication;
repl.PublisherDatabase = AppConstant.PublisherDatabase;
repl.PublisherLogin = AppConstant.PublisherLogin;
repl.PublisherPassword = AppConstant.PublisherPassword;
repl.Publication = AppConstant.Publication;
repl.Subscriber = AppConstant.Subscriber;
repl.SubscriberConnectionString = AppConstant.localConnection;
repl.AddSubscription(AddOption.ExistingDatabase);
// 跟 SQL Server 数据库进行同步
repl.Synchronize();
// 清理 repl 对象
repl.Dispose();
}
catch (SqlCeException ex)
{
MessageBox.Show(ex.ToString());
}/**/
}
在执行repl.Synchronize();的时候就出错,"将数据发送到运行IIS的计算机的请求失败,有关详细信息,请参阅HRESULT"..
@郁闷的小鱼儿
此方法是用SQL Server Compact 3.1生成的,我记得生成的文件可以用于SQL Server Mobile 3.0的。我看到你的错误信息,那台安装了SQL Server 2005的机器好像是SQL Server Mobile,没有安装SQL Server 2005 SP2来支持SQL Server Compact。
你好,我下载了你的源码例子,但编译却出现了:
未处理的“System.DllNotFoundException”类型的异常出现在 System.Data.SqlServerCe.dll 中。
其他信息: 无法加载 DLL“sqlceme30.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。请问是什么问题
@lwm
你的PC没有安装SQL Server Compact 3.1 for Desktop版本。
黎老师,给个SQL Server Compact 3.1 for Desktop版本的下载链接吧,谢谢
黎老师,我的PC安装了SQL Server Compact 3.1 for Desktop版本后,运行了程序还是出现了
未处理的“System.DllNotFoundException”类型的异常出现在 System.Data.SqlServerCe.dll 中。
其他信息: 无法加载 DLL“sqlceme30.dll”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)。请问是什么问题
@lwm
试一试把“C:\Program Files\Microsoft SQL Server Compact Edition\v3.1”目录下的DLL复制到你的程序目录。
老师,请教个问题:我用c#做了个数据库创建工作,在pda上运行成功,生成.sdf文件,然后我想用isqlw20进行连接,出现如下错误:
Error:0x80004005 E_FAIL
Dsecription:the file is not a valid database file
请问是什么问题?谢谢
@c#c#c#c#
可能是版本问题,例如你创建sdf文件的程序引用的sqlce库是一个3.0版本的,而你用isqlw20(不确定这个是不是一个sqlce 2.0的),这样就无法识别高版本的sdf数据库文件了。
isqlw20应该是sql ce2.0,我是完全按照sql ce的步骤注册的,怎么才能创建个sqlce 2.0识别的sdf文件呢
@c#c#c#c#
只要使用的sqlce版本对应就可以了。
老师,我的pda装的是sql2.0的,怎么升级到3.1?谢谢
教授:
你好, 请教个问题,我在做RDA同步时,出现"SQL Mobile encountered problems when opening the database"这个错误,我设备上装的是sql ce2.0,在地址栏中输入 http://455affb590b84ba/sqlce/sscesa20.dll,显示正确:SQL Server CE Server Agent,代码如下:
string rdaOleDbConnectString = "Provider=SQLOLEDB;Data Source=192.168.18.110;Initial Catalog=student;Integrated Security=false;User ID=sa;password=;";
string localString = (@"Data Source =\My Documents\gg.sdf;Password=12;");
SqlCeRemoteDataAccess rda = null;
try
{
// Try the Pull Operation
rda = new SqlCeRemoteDataAccess();
rda.InternetLogin = "";
rda.InternetPassword = "";
rda.InternetUrl = "http://455affb590b84ba/sqlce/sscesa20.dll";
rda.LocalConnectionString = localString; MessageBox.Show("ok1");
rda.Pull("student", "SELECT * FROM student", rdaOleDbConnectString, RdaTrackOption.TrackingOnWithIndexes);
//rda.Pull("student", "SELECT * FROM student", rdaOleDbConnectString);
MessageBox.Show("ok");
}
catch (SqlCeException ex)
{
MessageBox.Show(ex.Message);
}
finally
{
rda.Dispose();
}
请问是什么问题,谢谢
我在PC机上sqlce2.0,sqlce3.0都装了,这个会不会有影响呢,而且在IE地址栏输入时都能显示成功。
老师:
我的sqlce处在电脑的D:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v3.0\wce500\armv4i位置,我安装的sqlce包下的sqlce30.wce5.armv4i.CAB、sqlce30.repl.wce5.armv4i.CAB、sqlce30.dev.chs.wce5.armv4i.CAB 3个包,然后用查询分析器创建数据库,但创建失败,提示“IID_IDBDataSourceAdmin”请问是什么问题?
请问老师,如果我想把ORACLE中的数据导入到SQL 2005中,那该如何呢?谢谢
黎老师,您好,我一直想问的一个问题是:开发环境仅有Sql Server Express Edition能否实现移动设备直接访问Sql Server数据库,以及RDA,也就是说Sql Server Express Edition替代sql server 2005的功能?因为毕竟Sql Server Express Edition容易安装的 ,谢谢!
@ldufo
RDA应该是可以的,合并复制就不行,移动设备直接访问sql express也是可以的。
楼主你好,按照你上面说的,我把SQL Server Compact 3.1在PC安装完后,用vs2005建立一个wince的设置应用程序,引用的SqlServerCe.dll文件是C:\Program Files\Microsoft SQL Server Compact Edition\v3.1里面的,代码如下:
private void button1_Click(object sender, EventArgs e)
{
try
{
if (File.Exists("mydata.sdf"))
{
File.Delete("mydata.sdf");
}
SqlCeEngine engine = new SqlCeEngine("Data Source=mydata.sdf");
engine.CreateDatabase();
MessageBox.Show("create database success!");
}
catch (SqlCeException ex)
{
MessageBox.Show(ex.Message);
}
}
功能是在设备上创建一个sdf文件.
编译运行成功.在PC上执行生成的.exe文件,点击按钮在PC上可以生成一个sdf文件,但是copy到实际的终端设备上却提示
无法找到PInvoke DLL"sqlceme30.dll",copy的时侯把sqlce30的dll文件全都复制到终端设备上了,终端设备是wince5.0,请问这是为什么?
高手请教:
我安装了VS2005专业版,sql ce 数据库文件已经建立,在程序运行时,建立联系的时候发生[未能加载文件或程序集“System.Data.SqlServerCe, Version=9.0.242.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。]这个错误,请教是什么原因?
代码如下:
Dbconnect^ myDbconnect=gcnew Dbconnect;
myDbconnect->sqlGetConnectionString();
myDbconnect->mobileGetConnectionString();
即第三句总是报错
黎老师,您好,按照你的说的,我把对应的.cab文件copy到设备里,
但我的设备内核已经把sqlce2.0装进去了,我从注册表把它删除,重启,然后把PC里的sqlce30.dev.ENU.wce5.armv4i.CAB,
sqlce30.repl.wce5.armv4i.CAB,
sqlce30.wce5.armv4i.CAB
这三个文件copy到wince设备里,分别安装成功后,运行以前那个程序,还是提示:无法找到PInvoke DLL"sqlceme30.dll",
打开设备里的isqlw30.exe,新建一个.sdf文件,提示"Failed to initialize the provider,please make sure that sql server mobile edition is properly installed"
我的设备处理器是ARM920T,是不是应该copy上面三个文件呢?请指教.谢谢!
黎老师您好,我想问下,为什么对.sdf进行压缩CompactDatabase(),一点效果没有,在压缩前需要做什么设置不?
不知道你有没碰到过这个问题
@fzt
请确认设备端的注册表是否有以下键值:
HKEY_LOCAL_MACHINE\Software\Microsoft\Microsoft SQL Server 2005 Compact Edition Core
HKEY_LOCAL_MACHINE\Software\Microsoft\Microsoft SQL Server Compact Edition
@liaoxh
这个方法是用于回收数据库文件中的空间,对使用了一段时间的数据库文件才有明显效果。
@刘为
请问你的程序是用VC开发的吗?另外你的程序是在哪里运行?
黎老师:
我装的是C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v3.0\wce500\armv4i下面的三个cab文件,都安装成功.
在注册表HKEY_LOCAL_MACHINE\Software\Microsoft\下有三个键值:
HKEY_LOCAL_MACHINE\Software\Microsoft\SQL Mobile 2005
HKEY_LOCAL_MACHINE\Software\Microsoft\SQL Mobile 2005 [EN]
HKEY_LOCAL_MACHINE\Software\Microsoft\SQL Mobile 2005 Replication
但是没有你所说那两个键值,是不是我装的三个cab文件不正确呢?
@fzt
那表示注册表信息已经写入成功了,看上去安装没有什么问题。你再尝试一下将7个sqlce(*)e30.dll文件全部复制到程序所在目录试试吧,如果还是不行那就没办法了,只好把sql mobile定制到WINCE5.0的ROM里面。
想问一下博主,你的示例是不是直接运行就可以了,我用VS2008的,打开你的程序编译也通过了,但是运行的时候,老抛出异常而且每次都不一样(1562,110,1391...),我是使用自己创建的数据库,不知道需不需要添加其他的步骤,我只是简单的把.sql中的表结构和连接字符串给改下。
另外想问下博主,用C#创建的数据库,能不能用VC++来打开啊?或者,通过SQL Server Management Studio能不能访问?
我碰到了跟“郁闷小鱼”一样的错,就是使用SQL Server 2005 打不开创建的.sdf数据库文件,我已经安装过了SQL Server 2005 SP2
@liaoxh
VS2008自带了SQL Server Compact 3.5,那么用VS2008编译后,生成的SDF数据库文件,要用VS2008连接,或者用SQL Server 2008 Management Studio连接。
不太明白您的意思。。。。sdf文件我不是通过VS2008编译后产生的,而是用您的示例程序得到的,我本来想用SQL SERVER 2005 Management Studio连接看下里面的数据对不对,可是连不上?难道一定要用SQL SERVER 2008?
另外我原先有用VC++实现了一个连接sdf的ConnectDB(),但是用这个函数也打不开您(c#)示例生成的sdf文件,却能正确打开,我用VC++生成的sdf文件,难道这也有接口兼容的问题吗?
另外还想问下,SQL Server Compact 3.5有没批量插入数据的功能,如果有,对应的SQL 语句怎么写了?
@liaoxh
你可以用SQL Server Management Studio Express Edition 2008打开SQLCE3.5的数据库。
没有批量插入数据的功能。
请教楼主...
转换时出现错误
在 System.Data.SqlServerCe.SqlCeException 中第一次偶然出现的“System.Data.SqlServerCe.dll”类型的异常
The specified table does not exist. [ list ](表名没有错啊,为什么找不到呢?)
是怎么回事啊...
另外...我的我用的是sql server 2005开发版
我刚开始的时候也出现了85楼的那个问题,也安照88楼黎老师那个方法去做了,可又出来这个问题:
===================================
无法连接到 D:\Realty_ce.sdf。
===================================
未指定的错误 [ 3505053,3004180,D:\Realty_ce.sdf ] (SQL Server Compact Edition ADO.NET Data Provider)
------------------------------
程序位置:
在 System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
在 System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
在 System.Windows.Forms.Control.Invoke(Delegate method)
在 Microsoft.SqlServer.Management.UI.ConnectionDlg.Connector.ConnectionThreadUser()
现在搞得头都晕了,希望黎老师帮帮学生。
请问楼主 能在SQL CE数据库怎么判断表示否存在和判断网络连接是否正常! 用的是GPRS网络 我用的是VS2005 CE5.0
请楼主帮个忙!!非常感谢!
楼主,您好!
SqlCeResultSet 如何更新现有DB中的数据啊?
record = resultSet.CreateRecord();
record.SetValues(values);
resultSet.Insert(record);
这里每次都是新增加,如何实现Update呢?
难道要先Delete?
另外,
record = resultSet.CreateRecord();
record.SetValues(values);
resultSet.Insert(record);
如何得知是否成功增加?
resultSet.Insert(record)不会返回影响行的
黎老师您好!
在无线网络(wifi)中能通过RDA实现“PDA端(wince)与服务器数据库(sqlserver)进行时时数据交换(读,写)”吗? 搭建的无线网络其实就是一个内部局域网(非公网,服务器也在内部局域网中)
为什么我在PULL就要报"NUMBER:80072EE2 NATIVE_ERROR:28037 SOURCE:"Microsoft SQL Server 2000 Mobile Editon" 的错误,但是在PDA端的IE中可以打开"http://服务器的IP地址/RDA/sscesa20.dll",
请问老师是什么原因呢?能通过RDA实现无线网络中的时时数据交换吗?谢谢老师
黎老师您好!
在无线网络(wifi)中能通过RDA实现“PDA端(wince)与服务器数据库(sqlserver)进行时时数据交换(读,写)”吗? 搭建的无线网络其实就是一个内部局域网(非公网,服务器也在内部局域网中)
为什么我在PULL就要报"NUMBER:80072EE2 NATIVE_ERROR:28037 SOURCE:"Microsoft SQL Server 2000 Mobile Editon" 的错误,但是在PDA端的IE中可以打开"http://服务器的IP地址/RDA/sscesa20.dll",
请问老师是什么原因呢?能通过RDA实现无线网络中的时时数据交换吗?谢谢老师