我正在SQL Server和本地SQL Server压缩数据库之间移动数据。我使用标准的DataAdapter.Fill等填充了一个数据集。我然后将该数据集传递给另一个尝试更新本地SQL Compact DB的函数。
所以基本上我想从DB(SQL Server)上提取一个带有单个数据表(现在)的数据集,并将其扔到另一个数据库(SQL Compact)中。
(是的,我知道有这样的工具和同步框架,这种方法有其他原因)
要检测更改,我正在使用数据版本(我自己的滚动)和ID。因此,如果ID是>我们拥有的最高值然后将该行标记为已添加,否则如果该行的数据版本更高,则将该行标记为已更改。
if (Convert.ToInt32(row["SettingID"]) > id)
{
row.AcceptChanges();
row.SetAdded();
}
else if(Convert.ToInt32(row["DataVersion"]) > dv)
{
row.AcceptChanges();
row.SetModified();
}
删除处理略有不同,这在这里并不重要。
然后我创建一个SqlCeAdapter来尝试将记录插入/更新到CE数据库中。
using (SqlCeDataAdapter ad = new SqlCeDataAdapter("select * from " + tableName, Connection))
{
using (SqlCeCommandBuilder cb = new SqlCeCommandBuilder(ad))
{
cb.ConflictOption = ConflictOption.OverwriteChanges;
ad.UpdateCommand = (SqlCeCommand)cb.GetUpdateCommand();
ad.InsertCommand = (SqlCeCommand)cb.GetInsertCommand();
ad.FillSchema(ds, SchemaType.Source); //Tried both types and not doing this.
ad.RowUpdating += ad_RowUpdating;
ad.RowUpdated += ad_RowUpdated;
int result = ad.Update(ds, tableName);
}
}
对于插入物,这种方法很好 - 它们都可以通过。
更新不起作用。
如果我检查传入的数据表的行(即在上面的using语句之后),它们的状态已经改变,这是正确的。 Update方法返回要更新的正确行数,但它们没有更改(它位于!)。没有例外。
我订阅了RowUpdating和RowUpdated事件,RowUpdating方法会触发每一行。当我查看SqlCeRowUpdatedEventArgs时,每一行的状态为SkipCurrentRow,命令对象为null。 RowUpdated事件永远不会触发。
为什么修改了状态并且使用了SkipCurrentRow?
如果我修改它并创建目标数据集并使用源中的行更新它,则会触发两个事件并进行更新。再也不知道差异是什么。我已经尝试比较数据集和数据表的属性,它们看起来完全相同。
我认为这应该很简单,但它是前额 - >桌面界面情况之一。
有什么想法吗?