【发布时间】:2020-05-25 20:00:57
【问题描述】:
在调试以下代码时,我发现 forEach 需要花费大量时间,将 6000 条记录的状态从 EntityState.Unchanged 更改为 EntityState.Detached 在我的本地开发环境中大约需要 16 分钟。
'where' 表达式正在过滤记录,而 'update' 表达式仅更新单个列。
我尝试将 ProxyCreationEnabled 和 LazyLoadingEnabled 设置为 false,但仍然需要相同的时间。这段代码有什么问题?
DbSet = Context.Set<T>();
...
...
public virtual int UpdateDB(Expression<Func<T, T>> update, Expression<Func<T, bool>> where)
{
var recordsUpdated = DbSet.Where(where).Update(update);
foreach (var e in DbSet.Where(where))
{
var state = Context.Entry(e).State;
Context.Entry(e).State = EntityState.Detached;
state = Context.Entry(e).State;
}
return recordsUpdated;
}
}
【问题讨论】:
-
这个 Update 方法到底发生了什么?我怀疑你在那里打电话给
SaveChanges并且有一些你试图“重置”的静态上下文。这是几种不良做法的结合。 -
@GertArnold 在这段代码中,我们尝试使用 where 和 update 表达式直接更新 DbSet。我发现
var recordsUpdated = DbSet.Where(where).Update(update);行执行得非常快,但是Context.Entry(e).State = EntityState.Detached;行似乎需要更多时间循环每条记录,这里我们试图将状态从未更改更改为已分离。 -
这并不能真正回答我的问题。我试图找出你为什么要做你正在做的事情。您不需要将状态设置为分离。它可能使更改跟踪器非常忙碌(在臃肿的上下文中一直调用 DetectChanges)。您应该简单地处理上下文。这种更新,如果使用 EF 完成,应该通过创建存根实体来完成。
-
@GertArnold 很抱歉我对 EF 世界很陌生。我正在尝试分离实体,以便 EF 不跟踪它,但这看起来是个非常糟糕的主意,因为它使更改跟踪器保持忙碌。我将阅读更多关于处理上下文的内容。谢谢。
标签: c# entity-framework linq entity-framework-6 query-performance