DbContext破坏附加的实体:为什么?

时间:2012-07-07 11:55:22

标签: c# .net entity-framework

我有一些这样的代码:

Activity[] GetAllActivities() {
  using (ScheduleContext ctx = new ScheduleContext())
    return ctx.Activities.AsNoTracking().ToArray();
}

目标是为某些数据提供一个非常简单的内存缓存:Activities映射到db视图,该视图总结了我需要的所有内容。

如果我省略 AsNoTracking,则返回的对象被非确定性地破坏:返回的对象的属性设置不正确,并且通常一个对象的属性值在其他对象中重复属性。没有警告或例外;既不是EF4.3.1也不是EF5rc2。 CLR 4和4.5候选版本都表现出相同的行为。

Activity个对象非常简单;仅包含基本类型的非虚拟属性(intstring等),并且与任何其他实体没有密钥或关系。

这是预期的行为吗?我在哪里可以找到关于此的文档?

我理解,一旦相关DbContext消失,显然更改跟踪无效,但我很惊讶物化属性在没有警告的情况下被破坏。我最担心的是,在一个更复杂的场景中,我会忘记AsNoTracking,并且会得到一些看似合理但错误的结果。

编辑 该实体如下所示。谢谢Jonathan&克里斯托夫;确实有一个列被推断为ID!

public class Activity
{
  public string ActivityHostKey { get; set; }
  public int ActivityDuration { get; set; }
  public int ActivityLastedChanged { get; set; }
  public string ActivityId { get; set; }//!!!
  public string ModuleHostKey { get; set; }
  public string ModuleName { get; set; }
...

1 个答案:

答案 0 :(得分:3)

我认为“经常有一个对象的属性值在其他对象的属性中重复”,并且Activity对象“并且没有键”是这里的关键信息(没有双关语意)。

导入View(显然没有主键)时,EF会猜测主键是什么。如果随后启用了跟踪,则它使用该主键确保在内存中仅创建每个实体的单个副本。这意味着如果您为字段加载两行具有相同值的EF,则猜测PK是PK,第二行的值将覆盖第一行。

对于“非确定性损坏”的数据,这可能是因为数据库不保证返回行的顺序,并且它是EF中的“最后胜利”过程,因此如果订单记录的变化来自DB,保持其值的记录也会发生变化。

尝试将更多列标记为主键的一部分,或者修改视图(或EDMX中的DefiningQuery)以包含基于ROW_NUMBER function的列,以便您可以将其用作主键。