entity framework和DbContext – 对象跟踪

我对Entity Framework中DbContext的使用有点困惑。 这是我很困惑的场景。

  • 我使用dbcontext中的linq查询来获取数据。 就像是:

    List transactions = DefaultContext.Transactions.ToList(); 
  • 然后我直接在数据库中更新该查询中返回的一个事务中的列。

  • 然后我再打电话:

     List transactions = DefaultContext.Transactions.ToList(); 

当列表返回这次时,它不会反映我在运行update语句时所做的更新/更改,除非我遍历所有事务并重新加载它们:

 foreach (DbEntityEntry item in DefaultContext.ChangeTracker.Entries()) { DefaultContext.Entry(item.Entity).Reload(); } 

这是正常的行为吗? 我假设在我的初始查询中,它们被附加到对象上下文。 然后当我第二次查询时,它不会访问数据库,只是从对象上下文中提取实体,除非我清除/分离或单独重新加载所有实体。

这是正常的,并且在DbContext API固定行为的情况下,因为从一些非常奇怪的原因, DbSetDbQuery都没有公开MergeOption属性。 对于ObjectContext API,您可以通过在ObjectSetObjectQuery上公开的MergeOption设置行为。 因此,如果您想刷新数据库中的值(并丢失更改),您可以执行以下操作:

 ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext; ObjectSet set = objectContext.CreateObjectSet(); set.MergeOption = MergeOption.OverwriteChanges; List transactions = set.ToList(); 

如果您只想刷新事务但不想丢失更改,则可以使用MergeOption.PreserveChanges

这取决于DefaultContext.Transactions查询的MergeOption 。 默认值AppendOnly 不会覆盖上下文中已有的对象。 您可以将其更改为OverwriteChanges以获得您期望的行为。

与上述相关,当我遇到同样的错误时,这就是我降落的地方。 但我想在我的情况下将Merge Option设置为No Tracking 。 当我有一个试图关闭IQueryable的对象跟踪的excel导出方法时,我碰到了这个。 通过我不会改变的大量数据,我不需要任何更改跟踪。

尝试将一些IQueryables转换为类ObjectQuery(但在其他人上取得成功)时,类似下面的代码行将失败。

 var y = ((ObjectQuery)query).MergeOption = MergeOption.NoTracking; 

相反,我用AsNoTracking的用法取而代之

 query = query.AsNoTracking(); 

回到最初的问题,这可能类似于下面的,在System.Data.Entity中添加的DBQuery上的Extention方法

 List transactions = DefaultContext.Transactions.AsNoTracking().ToList(); 

半相关文章: https : //msdn.microsoft.com/en-us/library/hh949853(v = vs133).aspx