當我們的代碼只有一些實體的屬性被允許改變時,我們有一個場景。爲了保證這一點,我們有類似下面的代碼:強制實體框架返回一個新的實例
public void SaveCustomer(Customer customer)
{
var originalCustomer = dbContext.GetCustomerById(customer.Id);
if (customer.Name != originalCustomer.Name)
{
throw new Exception("Customer name may not be changed.");
}
originalCustomer.Address = customer.Address;
originalCustomer.City = customer.City;
dbContext.SaveChanges();
}
這段代碼的問題是,調用dbContext.GetCustomerById
總是不給我Customer
類的新實例。如果客戶已經從數據庫中提取,Entity Framework會將實例保存在內存中,並在每次後續的調用時返回它。
這導致我們遇到了實際問題 - customer
和originalCustomer
可能指的是同一個實例。在這種情況下,customer.Name
將等於originalCustomer.Name
,我們將無法檢測到它是否與數據庫不同。
我想大多數其他ORM也存在同樣的問題,因爲身份圖設計模式。
任何想法如何解決這個問題?我能以某種方式迫使EF永遠給我一個客戶類的新實例嗎?
或者我們應該重構代碼嗎?有沒有人知道這種情況下有什麼好的設計模式?
GetCustomerById從哪裏來?另外,你的上下文的壽命是多少? – ken2k 2012-02-21 10:09:03
啊,對不起。 GetCustomerById只是DbSet .Find()的包裝方法。生命週期是根據HTTP請求。 –
jhu
2012-02-21 10:18:05
如果你不希望'Name'被改變,只是不允許上層代碼與'Customer'實體一起工作(=創建新的類,其中'Name'將是隻讀的)或者隱藏setter。 – 2012-02-21 11:05:47