2014-10-29 56 views
3

我想使用的UnitOfWork和存儲庫模式,我有以下的「更新」的方法,如果我替換錶行(ID,顏色,年)的所有元素,工作正常。GenericRepository模式更新方法

public virtual void Update(TEntity entityToUpdate) 
{ 
    dbSet.Attach(entityToUpdate); 
    (entityToUpdate).State = EntityState.Modified; 
} 

但我想更新只是我傳遞(ID &顏色)的特定列。它會覆蓋其他元素(年份)。

因此,舉例來說,我有一個數據庫,記錄在我的汽車表:

Id = 1, 
color = "red" 
year = 2010 

,如果我像這樣更新...

var location = new Car 
{ 
    Id = 1, 
    color = "blue" 
}; 


unitOfWork.CarRepository.Update(car); 

現在的戰績是:

Id = 1, 
color = "blue" 
year = null 

我該如何重寫我的通用存儲庫方法來改變我所提供的內容? (即保持年份值)

回答

4

您將無法在通用存儲庫模式中合理做到這一點。你真的沒有必要使用這種模式。 EntityFramework已經是一個通用的存儲庫,爲什麼你需要將它包裝到另一個通用的存儲庫中?這種抽象增加了負值。

你想從你的控制器封裝數據庫的使用(應該永遠不會成爲一個MVC控制器的DbContext)但是你並不需要任何特殊的方式這樣做。只需將DbContext注入一個可以工作的類中即可。

而且大部分工作模式的單位是一個反模式,如果你通過UOW左右。這會在你的應用程序中產生一些非常瘋狂的耦合問題,這些完全不相關的代碼能夠影響很大程度上不同的代碼段。

刪除通用存儲庫並直接在您的服務/ DAL /資源類(不管您想要調用它)內使用EF將使您可以使用EF的全部功能。這將允許非常簡單地進行部分更新。

要使用通用存儲庫進行部分更新,您需要一些繁重的動態代碼來處理映射。老實說,我可以理論上寫這個,但我知道足夠知道不寫這個。你越是抽象地繪製它變得越脆弱,幾乎不可能預測未來如何處理映射。這就是爲什麼像AutoMapper這樣的整個庫可以處理如何完成映射的無限數量的組合。 AutoMapper也有點不對,如果它可以做基本的自動映射,大多數情況下AutoMapper的用例仍然全部爲靜態映射不是動態映射。您需要創建動態映射,即水晶球映射。

+0

直接使用實體時,如何測試服務/ DAL /資源?你不需要嘲笑你需要測試的服務/ DAL /資源方法中使用的每個實體方法嗎? – afarazit 2016-10-24 07:44:00

+0

@afarazit我從不嘲笑數據庫,這是毫無意義的。我嘲笑抽象,'DAL'。有時候,這可能意味着我的模擬DAL使用字典來模擬[快速]集成測試的持久性。 – 2016-10-31 17:48:10

+0

@ChrisMarisic - 您可以指出一些描述模擬DAL而不是數據庫的實現的文章。因爲我也一直在嘲笑db來測試我的服務。 – Nanu 2017-08-18 17:04:35

0

您編寫的更新方法假定您已經開始使用具有屬性設置的現有實體對象。倉庫假定您的業務邏輯是這樣工作的:

var car = repo.GetCar(id); 

car.prop1 = "new value"; 
car.prop2 = "another new value"; 

repo.update(car); 

這將保留您設置的任何先前值。

+0

2個查詢爲1個更新? – Piyey 2016-12-02 17:24:21