2013-03-20 44 views
1

我在使用存儲庫和工作單元模式將對象添加到基礎持久性存儲(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(); 
} 

但這似乎不是最佳解決方案。有任何想法嗎?

回答

0

如果您要插入實體,則EF會插入整個圖形。

// Build graph 
var customer = new Customer(...); 
customer.LegalAddress = new Address(...); 
var account = new Account(); 
account.Customer = customer; 
var order = new Order(); 
order.BuyerAccount = account; 
// Here all Navigation properties updated 
// and state of all entities set to Added 
_orderRepository.Add(order); 
// Here all entities inserted in transaction, PK and FK updated 
context.SaveChanges(); 

當您只需要插入圖的一部分時,複雜性就開始了。然後你應該手動設置圖形中的實體狀態。

+0

這隻有在實體之間存在獨立關聯時纔有效,我相信? – 2013-03-20 15:10:37

+0

@TommyJakobsen你是什麼意思*獨立協會*?閱讀EF中的關係http://stackoverflow.com/a/15221140/470005 – 2013-03-20 15:11:26

+0

由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