代码之家  ›  专栏  ›  技术社区  ›  R. Schreurs Rohith

在实体框架DB优先的方法中,我如何用具有相同密钥的另一个实体替换一个实体?

  •  4
  • R. Schreurs Rohith  · 技术社区  · 12 年前

    我正在首先使用EF 5数据库编程一个MVC 4网络应用程序。我有一些看似微不足道的问题,但我找不到合适的解决方案。这些问题与对象状态管理器有关。

    在最简单的场景中,一切都很好:我使用Find从数据库中读取实体,将它们放在视图中,等待响应,重建实体,使用Attach、EntityState.Modified和SaveChanges将其写回。如果在处理请求时,我再次从数据库中获取实体,就会出现问题。

    如果:
    1.出于某种原因,我想检查原始实体的一些值。
    2.我的一些值不需要修改,因为它们标识了实体。我使用DisplayFor将这些放在我的视图中仅供参考。当然,重新构建的模型不具有这些值。我从数据库中获取原始实体,并在控制器中使用TryUpdateModel将其与视图中的模型合并。

    调用Attach时,我得到一个异常“ObjectStateManager中已经存在一个具有相同键的对象。ObjectStateManager无法跟踪具有同一键的多个对象。”。

    如果我使用 Context.Entry(t).CurrentValues.SetValues(t); 而不是 DbSet.Attach(t); ,我得到以下异常:

    Member 'CurrentValues' cannot be called for the entity of type 'Price' because the entity does not exist in the context. To add an entity to the context call the Add or Attach method of DbSet<Price>.

    据我所知,有两个实体实例具有特定的密钥。如果有的话,我想做一个我想保存的,代替现在的。我希望这是自动的,也就是说,不必告诉我是否已经有另一个必须更换的。

    有办法做到这一点吗?

    1 回复  |  直到 11 年前
        1
  •  1
  •   R. Schreurs Rohith    10 年前

    与此同时,我已经开始使用模型优先方法,所以我不太确定以下方法是否适用,但我认为其中一些可能有用。

    1. 使用运行查询 someContext.someDbSet.AsNoTracking() 如果 您只想查找一些数据,但不打算更新 数据库发生更改。看见 AsNoTracking 在MSDN上。
    2. 将某些模型特性排除在更新之外。这将帮助您更新例如用户配置文件,而无需更新存储在同一模型中的哈希密码。

      someContext.someDbSet.Attach(someModelInstance);
      var entry = substanceContext.Entry(someModelInstance);
      entry.State = EntityState.Modified;
      entry.Property("somePropertyToIgnore").IsModified = false;
      substanceContext.SaveChanges();
      

    如果你看看 SQL语言 在第二个解决方案中生成,您会注意到该字段 某些属性到Igore 被排除在外 集合 条款