我在使用存儲庫和工作單元模式將對象添加到基礎持久性存儲(MS SQL Server 2012)時遇到了問題。問題是,一旦提交,生成的插入語句的順序出現錯誤順序,因此由於外鍵約束而失敗。實體框架,工作單元和生成的插入語句的順序
試想一下,我們要創建一個客戶,地址,賬號和訂單與一次性訂單行(單個提交):
using (var tx = new TransactionScope())
{
var address = new Address(...);
_addressRepository.Add(address);
var customer = new Customer(...);
customer.AssignLegalAddress(address.Id);
_customerRepository.Add(customer);
var account = new Account(..., customer.Id);
_accountRepository.Add(account);
var order = new Order();
order.AssignBuyerAccount(account.Id);
order.AddOrderLine(...);
order.AddOrderLine(...);
_orderRepository.Add(order);
_unitOfWork.Commit();
tx.Complete();
}
爲了
所以對於要提交的客戶,地址應首先承擔責任,並且客戶在賬戶之前,最後是訂單之前的賬戶。所以我在不同的倉庫中調用Add的順序。
上面的存儲庫首先使用Entity Framework 5.0代碼,每個添加操作歸結爲將實體添加到基礎DbContext。我們可以將其翻譯爲:DbContext.Set<TEntity>().Add(entity)
。 對Commit的調用基本上調用DbContext.SaveChanges()。
問題是,EF似乎並不關心他們添加的順序。 雖然監視發送到提交的底層存儲的查詢,但我看到首先創建的地址非常好,但是執行了用於創建帳戶的插入語句。這失敗了,因爲客戶尚未創建。
有沒有一種方法可以讓EF在保存更改時考慮我們添加它們的順序?否則,我將不得不手動提交這些更改,例如:
using (var tx = new TransactionScope())
{
var address = new Address(...);
_addressRepository.Add(address);
_unitOfWork.Commit();
var customer = new Customer(...);
customer.AssignLegalAddress(address.Id);
_customerRepository.Add(customer);
_unitOfWork.Commit();
var account = new Account(..., customer.Id);
_accountRepository.Add(account);
_unitOfWork.Commit();
var order = new Order();
order.AssignBuyerAccount(account.Id);
order.AddOrderLine(...);
order.AddOrderLine(...);
_orderRepository.Add(order);
_unitOfWork.Commit();
tx.Complete();
}
但這似乎不是最佳解決方案。有任何想法嗎?
這隻有在實體之間存在獨立關聯時纔有效,我相信? – 2013-03-20 15:10:37
@TommyJakobsen你是什麼意思*獨立協會*?閱讀EF中的關係http://stackoverflow.com/a/15221140/470005 – 2013-03-20 15:11:26
由EF團隊[此處]描述他們(http://blogs.msdn.com/b/msdnforum/archive/2010/05 /07/foreign-key-association-in-entity-framework-4.aspx)。導航屬性。 – 2013-03-20 16:18:11