EF 4.1:读取错误(查询结果与数据库和内存值混合/合并)

时间:2013-06-25 19:37:31

标签: entity-framework

我有一个实体,例如,它有另一个实体的外键:

public entityA
{
   ....
        [ForeignKey("State")]
        public virtual int StateId { get; set; }
        public virtual States State { get; set; }
   ....
}

IDbSet<entityA> EntitiesA;

默认情况下,StateId最初初始化为10。

我将我的上下文初始化为数据库,我总是使用相同的。一旦使用using子句初始化,我会对EntitiesA集合中的某些实体进行一些更改(即将StateId设置为20),但我不使用context.SaveChanges()提交对数据库的更改,因为此时我不想要。

修改了一些实体后,我到达了我的应用中的一个点,我执行以下操作:

IQueryable<EntityA> entities = 
                context.EntitiesA.Where(e => e.StateId == 10);
foreach (EntityA _currentEntity in entities)
{
  ....
}

此时,由于我没有将更改保存到数据库,因此数据库中的实体继续将其状态设置为10(而不是修改为20),因此满足条件e.StateId == 10但实体包含其StateId为20所以我不明白这一点......

期望的行为是条件e.StateId不满足先前已修改为20的实例和仅包含其stateid仍为10(未修改)的项的实体。

有什么想法吗?似乎查询是针对数据库启动的,结果实际上是从内存中获取的......

1 个答案:

答案 0 :(得分:1)

行为是预期的,但是,这是令人困惑的。为了解决这个问题,你必须运行一个奇怪的查询,例如:

IEnumerable<EntityA> entities = context.EntitiesA
    .Where(e => e.StateId == 10)  // LINQ-to-Entities = filter in database
    .AsEnumerable()
    .Where(e => e.StateId == 10); // LINQ-to-Objects = filter in memory

foreach (EntityA _currentEntity in entities)
{
    ....
}

您的查询会在数据库中检索StateId = 10的实体。返回结果时,EF将遍历所有已加载的行,并检查具有相同键的实体是否已附加到上下文。

  • 如果是,它将在枚举中返回此附加实体,其中包含当前在内存中的所有值。默认情况下,EF不会更新已加载行中的值,因此已修改实体的StateId仍为20

  • 如果不是,它会将新实体(具有StateId 10)附加到上下文并将其作为枚举的一部分返回。

因此,您可以获得StateId 10或20的实体组合。基本上,您的查询意味着:“为我提供StateId 10 的所有实体在数据库中。“

通过在查询中附加.AsEnumerable().Where(e => e.StateId == 10),您可以过滤掉内存中StateId 10 {/ 1>}的实体。