考虑非常简单的数据库表:
CREATE TABLE UkTest(
id int NOT NULL,
uk int NOT NULL
)
Primary Key on id
Unique Key on uk
然后添加2行:
INSERT INTO UkTest (id,uk) VALUES(1,1);
INSERT INTO UkTest (id,uk) VALUES(2,2);
然后进行2次测试。
行:
var db = new Database1Entities();
var element1 = db.UkTest.FirstOrDefault(e => e.id == 1);
var element2 = db.UkTest.FirstOrDefault(e => e.id == 2);
element1.uk = 0;
element2.uk = 1; // overrides previous element1.uk value
var count = db.SaveChanges();
失败(在测试之前将uk值恢复为1和2!):
var db = new Database1Entities();
var element1 = db.UkTest.FirstOrDefault(e => e.id == 1);
var element2 = db.UkTest.FirstOrDefault(e => e.id == 2);
element2.uk = 0;
element1.uk = 2; // overrides previous element2.uk value
var count = db.SaveChanges();
// Cannot insert duplicate key row in object 'dbo.UkTest' with unique index 'UK_UkTest'
请参阅ObjectContext.SaveChanges()
按主索引的顺序检查行。
有没有办法强迫自己订购?
答案 0 :(得分:2)
除非你两次调用SaveChanges()
,否则无法控制实体框架将发送到数据库的SQL语句的顺序。您可以将多个SaveChanges()
调用包装到外部事务中,以确保整个操作仍然是事务性行为:
using (var scope = new TransactionScope())
{
using (var db = new Database1Entities())
{
var element1 = db.UkTest.FirstOrDefault(e => e.id == 1);
var element2 = db.UkTest.FirstOrDefault(e => e.id == 2);
element2.uk = 0;
db.SaveChanges();
element1.uk = 2;
db.SaveChanges();
}
scope.Complete();
}
答案 1 :(得分:0)
感谢Slauma。我找到了解决方案。关键是将元素保存在几个ObjectContext实例中。
public class SavingElementsWithTransactionInOwnOrder
{
public void SaveElements ()
{
var db = new Database1Entities();
var element1 = db.UkTest.FirstOrDefault(e => e.id == 1);
element1.db = db;
db = new Database1Entities();
var element2 = db.UkTest.FirstOrDefault(e => e.id == 2);
element2.db = db;
element2.uk = 0;
element1.uk = 2;
var scope = new TransactionScope();
try{
element2.db.SaveChanges();
element1.db.SaveChanges();
scope.Complete();
}
finally{
scope.Dispose();
}
}
}
public partial class UkTest
{
public Database1Entities db { get; set; }
}