我的看法是:我们有一个生产数据库和一个集成数据库,我写了一个工具将生产数据库的某些数据迁移到集成数据库。为此,我使用:Entity Framework 6.0,.NET-Framework 4.5.2和数据库是MS SQL Server Standard(64位)13.0.5102。
我的问题:在将所有数据的删除保存在集成数据库中的同时,SaveChanges
方法抛出一个带有错误消息的DbUpdateConcurrencyException
存储更新,插入或删除语句影响了意外的行数(0)。自加载实体以来,实体可能已被修改或删除。
以下是通过该异常的代码:
using (var prod = new DbProdContext())
{
using (var @int = new DbIntContext())
using (var transaction = @int.Database.BeginTransaction(IsolationLevel.Serializable))
{
try
{
var stack = BuildStack(@int, ...); // buikds a stack of the tables where the latest pushed tables depdend only on already pushed tables
// Deleting everything in db
using (var x = log4net.NDC.Push("Deleting old content"))
{
foreach (var table in stack.Reverse())
{
var destSet = table.DestSet;
destSet.RemoveRange(destSet);
}
log.Info("Saving Changes...");
@int.SaveChanges(); // <-- throw exception
log.Info("Completed Saving Changes");
}
// code to insert the data
transaction.Commit();
}
catch (Exception ex)
{
// log
transaction.Rollback();
}
}
}
注意:变量stack
是集成数据库中表的堆栈,其中对于任何给定表t
,t
所依赖的所有表都在{{ 1}}被压入堆栈。
第二个注意事项:我测试了代码,并将数据从生产数据库的本地测试克隆迁移到集成数据库,而该数据库从未抛出此异常。
任何人都知道如何防止此错误或引起此错误的原因。
第三条注释:当前正在使用的注释中的集成数据库无法通过不同的过程对数据库进行并发更改。
我应该只为表创建sql drop语句,而不要使用t
答案 0 :(得分:0)
我应该只为表创建sql drop语句,而不是使用destSet.RemoveRange(destSet)
是的。你应该那样做。但是,如果您不想重新创建表,则应使用DELETE或TRUNCATE TABLE代替DROP TABLE。