Entity framework 强制实体框架返回新实例

Entity framework 强制实体框架返回新实例,entity-framework,orm,identity-map,Entity Framework,Orm,Identity Map,我们的代码中有一个场景,即只允许更改实体的几个属性。为了保证这一点,我们有类似的代码: public void SaveCustomer(Customer customer) { var originalCustomer = dbContext.GetCustomerById(customer.Id); if (customer.Name != originalCustomer.Name) { throw new Exception("Customer

我们的代码中有一个场景,即只允许更改实体的几个属性。为了保证这一点,我们有类似的代码:

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
类的新实例。如果已经从数据库中提取了客户,EntityFramework将把实例保存在内存中,并在每次后续调用时返回它

这就引出了实际问题-
客户
,而
原始客户
可能引用同一实例。在这种情况下,
customer.Name
将等于
originalCustomer.Name
,我们将无法检测它是否与数据库不同

我想,由于identitymap设计模式,大多数其他orm也存在同样的问题

有没有办法解决这个问题?我能强迫EF总是给我一个customer类的新实例吗


或者我们应该重构代码?有人知道这个场景有什么好的设计模式吗?

您可以尝试从上下文中分离实体,这将删除对上下文的所有引用(以及identitymap行为)。 因此,在将客户传递给您的方法之前,您可以将其分离:

yourContext.Detach(customer);

您可以尝试从上下文中分离实体,这将删除对上下文的所有引用(以及identitymap行为)。 因此,在将客户传递给您的方法之前,您可以将其分离:

yourContext.Detach(customer);

GetCustomerById
来自哪里?还有,你的生活背景是什么?啊,对不起。GetCustomerById只是DbSet.Find()的包装器方法。生存期为每个HTTP请求。如果您不想更改
名称
,请不要让上层代码与
客户
实体(=在
名称
将为只读的位置创建新类)或隐藏setter。
GetCustomerById
从何而来?还有,你的生活背景是什么?啊,对不起。GetCustomerById只是DbSet.Find()的包装器方法。生存期为每个HTTP请求。如果您不想更改
名称
,请不要让上层代码与
客户
实体一起工作(=创建新类,其中
名称
将为只读)或隐藏setter。这在技术上是正确的答案。若要从数据库中获取新实例,必须首先从上下文中分离以前的实例。这在技术上是正确的答案。若要从数据库中获取新实例,必须首先从上下文中分离以前的实例。