我们的代码中有一个场景,只允许更改实体的一些属性。为了保证这一点,我们有类似的代码:
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
类的新实例。如果客户已经从数据库中获取,则实体框架会将实例保留在内存中,并在每次后续调用时将其返回。
这导致我们遇到实际问题 - customer
和originalCustomer
可能会引用相同的实例。在这种情况下,customer.Name
将等于originalCustomer.Name
,我们将无法检测它是否与数据库不同。
我猜大多数其他ORM也存在同样的问题,因为身份图设计模式。
任何想法如何解决这个问题?我可以以某种方式强制EF总是给我一个新的客户类实例吗?
或者我们应该重构代码吗?有没有人知道这种情况的任何好的设计模式?
答案 0 :(得分:1)
您可以尝试从上下文中分离实体,这将删除对上下文的所有引用(以及identitymap行为)。 因此,在将客户传递给您的方法之前,您可以将其分离:
yourContext.Detach(customer);