C# 实体框架和DbContext对象跟踪
我对实体框架中DbContext的用法有点困惑。这是我感到困惑的情景C# 实体框架和DbContext对象跟踪,c#,visual-studio-2010,entity-framework,.net-4.0,entity-framework-4.1,C#,Visual Studio 2010,Entity Framework,.net 4.0,Entity Framework 4.1,我对实体框架中DbContext的用法有点困惑。这是我感到困惑的情景 我使用dbcontext中的linq查询来获取数据。比如: List<Transactions> transactions = DefaultContext.Transactions.ToList(); List transactions=DefaultContext.transactions.ToList(); 然后,我直接在数据库中更新查询中返回的一个事务中的一列 然后我再打电话: List<Tra
- 我使用dbcontext中的linq查询来获取数据。比如:
List<Transactions> transactions = DefaultContext.Transactions.ToList();
List transactions=DefaultContext.transactions.ToList();
- 然后,我直接在数据库中更新查询中返回的一个事务中的一列
- 然后我再打电话:
List<Transactions> transactions = DefaultContext.Transactions.ToList();
List transactions=DefaultContext.transactions.ToList();
foreach (DbEntityEntry<Transactions> item in DefaultContext.ChangeTracker.Entries<Transactions>())
{
DefaultContext.Entry<Transactions>(item.Entity).Reload();
}
foreach(DefaultContext.ChangeTracker.Entries()中的DbEntityEntry项)
{
DefaultContext.Entry(item.Entity).Reload();
}
这是正常的行为吗?我假设在我的初始查询中,它们被附加到对象上下文。然后,当我第二次查询时,它不会访问数据库,只是从对象上下文中拉出实体,除非我清除/分离或单独重新加载所有实体。这取决于
DefaultContext.Transactions
查询的MergeOption
。默认值,AppendOnly
,您可以将其更改为OverwriteChanges
,以获得所需的行为。这是正常的,在DbContext API的情况下是固定的行为,因为出于某种非常奇怪的原因,DbSet
或DbQuery
exposeMergeOption
属性。对于ObjectContext API,您可以通过在ObjectSet
和ObjectQuery
上公开的MergeOption
设置行为。所以,如果要从数据库中刷新值(并丢失更改),可以执行以下操作:
ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext;
ObjectSet<Transactions> set = objectContext.CreateObjectSet<Transactions>();
set.MergeOption = MergeOption.OverwriteChanges;
List<Transactions> transactions = set.ToList();
ObjectContext ObjectContext=((IOObjectContextAdapter)dbContext).ObjectContext;
ObjectSet=objectContext.CreateObjectSet();
set.MergeOption=MergeOption.OverwriteChanges;
列表事务=set.ToList();
如果您只想刷新事务,但不想丢失更改,可以使用
MergeOption.PreserveChanges
与上述内容相关,当我遇到同样的错误时,这就是我着陆的地方。但在我的例子中,我想将合并选项设置为无跟踪。当我有一个excel导出方法试图关闭IQueryable的对象跟踪时,我遇到了这个问题。在浏览大量我不会更改的数据时,我不需要任何更改跟踪
在尝试将某些iQueryTables强制转换为类ObjectQuery时,与下面类似的一行代码将失败(但在其他代码上成功)
相反,我将其替换为使用AsNoTracking
query = query.AsNoTracking();
回到原来的问题,这可能类似于下面在System.Data.Entity中添加的DBQuery扩展方法
List<Transactions> transactions = DefaultContext.Transactions.AsNoTracking().ToList();
List transactions=DefaultContext.transactions.AsNoTracking().ToList();
半相关文章:
感谢您指出这一点。当我使用DbContext时,我的查询不是ObjectQuery类型。所以我不能像var query=Defaultcontext.Transactions这样强制转换查询;to((ObjectQuery)query.MergeOption=MergeOption.OverwriteChanges;我需要使用linq样式的查询吗?我需要过滤返回的一些数据。我以前使用的是.Where(…但是现在我使用的是ObjectContext,它不知道我的实体类。但是现在如何过滤查询中的数据?我不想返回整个结果。您所说的“它不知道我的实体类”是什么意思。您可以使用ObjectContext编写与DbContext相同的linq查询。
List<Transactions> transactions = DefaultContext.Transactions.AsNoTracking().ToList();