【问题标题】:Two references to the same domain/entity model对同一域/实体模型的两次引用
【发布时间】:2012-07-06 20:01:50
【问题描述】:

问题

我想保存在用户编辑模型时已更改的模型属性。这就是我想做的...

  1. 检索已编辑的视图模型
  2. 获取域模型并映射回更新值
  3. 调用仓库的更新方法
  4. 获取“旧”域模型并比较字段的值
  5. 将更改的值(以 JSON 格式)存储到表中

但是,我在执行第 4 步时遇到了问题。似乎实体框架不想再次访问数据库来获取具有旧值的模型。它只是返回与我相同的实体。

尝试的解决方案

我尝试过使用Find()SingleOrDefault() 方法,但它们只是返回我目前拥有的模型。

示例代码

private string ArchiveChanges(T updatedEntity)
{
    //Here is the problem!
    //oldEntity is the same as updatedEntity
    T oldEntity = DbSet.SingleOrDefault(x => x.ID == updatedEntity.ID);

    Dictionary<string, object> changed = new Dictionary<string, object>();

    foreach (var propertyInfo in typeof(T).GetProperties())
    {
        var property = typeof(T).GetProperty(propertyInfo.Name);

        //Get the old value and the new value from the models
        var newValue = property.GetValue(updatedEntity, null);
        var oldValue = property.GetValue(oldEntity, null);

        //Check to see if the values are equal
        if (!object.Equals(newValue, oldValue))
        {
            //Values have changed ... log it
            changed.Add(propertyInfo.Name, newValue);
        }
    }

    var ser = new System.Web.Script.Serialization.JavaScriptSerializer();
    return ser.Serialize(changed);
}

public override void Update(T entityToUpdate)
{
    //Do something with this
    string json = ArchiveChanges(entityToUpdate);

    entityToUpdate.AuditInfo.Updated = DateTime.Now;
    entityToUpdate.AuditInfo.UpdatedBy = Thread.CurrentPrincipal.Identity.Name;

    base.Update(entityToUpdate);
}

【问题讨论】:

  • 这个代码是你更新repository之后的吗?从你的步骤听起来就是这样。如果是这样,那么是的,您将获得新模型;您更新了旧模型。如果你想这样做,你需要在更新之前获取旧模型。
  • @Tyrsius 以前没有。我添加了调用方法以获得更清晰的图片。
  • 您正在处理/更新的实体附加到上下文(跟踪)。这意味着如果您修改它,它将进入修改状态(这意味着当调用 SaveChanges 时,它将在 DB 中进行更新)。但是,当仅查询实体(SingleOrDefault 调用)时,由于实体附加到上下文(在内存缓存中),它将直接从上下文中检索,并且不会往返 DB。如果要从 DB 中检索实体,则需要从当前上下文中分离实体(然后重新附加它,以便对 SaveChanges 的调用实际上会更新 DB)。

标签: c# .net sql-server asp.net-mvc entity-framework


【解决方案1】:

问题是实体框架缓存的是它在 DbSet 中读取的对象。因此,当您第二次请求对象时,它不会进入数据库,因为它已经加载了它。

不过,好消息是 Entity 会自动跟踪原始值。有关如何获取它们的信息,请参阅此问题:How to get original values of an entity in Entity Framework?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多