2013-05-21 89 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