2013-05-21 51 views
0

我会向您介绍一些关于“真实交易”和“伪交易”的问题。 我认为实体框架实现了伪事务,我会告诉你为什么。UnitOfWork - 真实交易

// Partial Code 

// *** Transaction scenario *** // 
ObjectContext ctx = new ... 
ctx.Connection.Open(); 
using(var t = ctx.Connection.BeginTransaction()) 
{ 
var invoice = new invoice{ price=10, Customer="myClient"}; 
ctx.CreateObjectSet<invoice>().AddObject(invoice); 
ctx.SaveChanges(); 

// here I 've the ID invoice (I mean it like identity autoincrement) and I can execute some business logic basis on ID value 
var client = new client { Name="Robert", Address="some address", IdInvoice=invoice.ID} 
ctx.CreateObjectSet<client>().AddObject(client); 
ctx.SaveChanges(); 

// Persistence 
t.Commit(); // some error? t.Rollback 
} 


// *** PSEUDO Transaction scenario *** // 
ObjectContext ctx = new ... 

var invoice = new invoice{ price=10, Customer="myClient"}; 
ctx.CreateObjectSet<invoice>().AddObject(invoice); 

// here I haven't invoice ID (I mean it like identity autoincrement) and I CANNOT EXECUTE ANY business logic basis on ID value 
var client = new client { Name="Robert", Address="some address", IdInvoice=invoice.ID} // BAD: its value is zero 
ctx.CreateObjectSet<client>().AddObject(client); 

// Persistence 
ctx.SaveChanges(); 

注意,EF将更新ID值被称为唯一的SaveChanges之后且仅当存在发票和客户对象之间的关系,否则什么也不会正常工作。

所以,我的问题是:在unitOwWork模式中使用“真正的事务”是否是一个好习惯? 为什么EF让我们有可能偶然发现像我向你展示过的那个问题?

回答

0

SaveChanges可以发送多个命令到数据库,在你的情况下,它会发送两个INSERT语句 - 未连接和一个接一个。 SaveChanges将这些语句包装为由Entity Framework管理的转换,并且您无法控制其生存期。它从SaveChanges开始,并在所有语句已发送且在SaveChanges返回之前被提交或回滚。这笔交易是“真实的”。 INSERT都可以成功或者不成功。

在许多情况下,这是足够和方便的,你不必关心事务管理。

在您的特殊情况下,这是不够的,创建和管理您自己的外部交易是正确的解决方案。如果Customer的导航属性为Invoice,则不需要这样做。但是你不这样做,所以你需要这个单独的事务来获取数据库生成的关键值,并且仍然在事务中执行整个操作。

+0

完美..非常感谢你 – bit