2012-08-15 136 views
4

我想使用實體框架來保存域實體。我的項目的設置如下: -實體框架和存儲庫模式

  • UI:MVC(使用Automapper域實體和視圖模型之間的映射)
  • 域名:entites的,服務,存儲庫接口
  • 庫:實體框架(實施來自域層的接口)。使用Automapper在域實體和實體框架對象之間進行映射。

這很好,除非在我的服務中,如果我通過檢查存儲庫來驗證項目,然後執行更新。這失敗了,因爲實體框架標識映射已經看過該項目,我嘗試重新附加它。

我可以使用代碼如下(這將是更加通用)

 public void Update(Domain.Entities.Book entity) 
    { 
     Book newBook = _mapper.Map<Domain.Entities.Book, Book>(entity); 
     ObjectStateEntry cacheEntry; 
     if (_dataContext.ObjectStateManager.TryGetObjectStateEntry(_dataContext.CreateEntityKey("Books",newBook), out cacheEntry)) 
     { 
      _dataContext.Books.ApplyCurrentValues(newBook); 
     } 
     else 
     { 
      _dataContext.Books.Attach(newBook); 
      _dataContext.ObjectStateManager.ChangeObjectState(newBook, EntityState.Modified); 
     } 
     _dataContext.SaveChanges(); 
    } 

的問題是,我覺得有寫同一類的代碼刪除

 public void Delete(Domain.Entities.Book entity) 
    { 
     Book newBook = _mapper.Map<Domain.Entities.Book, Book>(entity); 
     ObjectStateEntry cacheEntry; 
     if (_dataContext.ObjectStateManager.TryGetObjectStateEntry(_dataContext.CreateEntityKey("Books", newBook), out cacheEntry)) 
     { 
      _dataContext.ObjectStateManager.ChangeObjectState(cacheEntry.Entity, EntityState.Deleted); 

     } 
     else 
     { 
      _dataContext.Books.Attach(newBook); 
      _dataContext.ObjectStateManager.ChangeObjectState(newBook, EntityState.Deleted); 
     } 
     _dataContext.SaveChanges(); 
    } 
我自己解決此問題

我確定必須有更好的方式來實現我想要做的事情,但是我不能爲我的生活找出什麼!

有關上述方法的任何其他一般性評論將被讚賞,因爲我即將在大型項目中使用它!

感謝

羅斯

+1

我想知道如何進入一個你不知道一個實體是否已經連接的情況。在像更新實體這樣的基本用例中使用像TryGetObjectStateEntry這樣的高級方法在我看來是代碼味道。另外請注意,您的更新依賴於'cacheEntry.Entity'代表數據庫中的原始狀態,否則「ApplyCurrentValues」和更改跟蹤將不會標記正確的屬性被修改爲執行正確的數據庫更新。你是否知道,當你甚至不知道這個實體是否已經連接? – Slauma 2012-08-15 17:13:46

+0

創建資源庫對象並獲取項目會導致項目被加載到EF中,然後轉換爲域項目。然後可以編輯該域項目,然後過去到存儲庫更新方法。然後這個域對象(使用AutoMap)變成一個分離的EF對象。由於密鑰已被保存,因此將其附加到EF將導致異常。我很驚訝這對人們來說不是一個更大的問題? – 2012-08-15 17:17:53

+0

我明白了。但是,爲什麼區分「域實體」和「EF實體」?沒有中間映射,ORM是否能夠堅持域實體? – Slauma 2012-08-15 17:44:14

回答

0

除非我完全誤解了你的問題,我覺得你的問題是DatabaseContext對象的多個實例。如果你從一個上下文實例中獲得一個對象,然後嘗試在不同的上下文實例中使用它,你將會得到很多異常:第二個上下文實例會看到對象已經連接,但是它不能使用它,導致它被附加到不同的上下文實例。

如果你只有一個上下文實例管理你的附加對象,它會看到已經附加的對象,並且只能使用它。而且,您不需要使用AutoMapper(通過成員智能克隆的方式進行高級技巧)將對象克隆到新實例以及任何其他可怕的「TryingToAttachObject」東西中。

我有很多與多個上下文實例相似的問題,直到我發現依賴注入和它的魔力:它會創建一個DBContext實例,並將它用於所有請求和EF管理。

+0

嗨,因爲我剛剛回復BigDaddy上下文只有一個實例,這並不解決它我害怕。 – 2012-09-02 09:27:30

1

像trailmax說的,它看起來像你有多個數據上下文。我會拍攝一個數據上下文。這可以通過創建一個通用存儲庫來完成。假設您在實體和存儲庫之間有1:1的關係,本文可能會幫助您實現目標:http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

+0

我只有1個上下文。在我的測試用戶界面應用程序中,我創建了一個存儲庫,並將其傳遞給服務。這不幸的是不是問題。 – 2012-09-02 09:26:34