当我执行以下语句时,我很想知道为什么查询重新调整此错误:
SelectFor(x => x.Id == id, true, false, "Scope.Hiring.Scopes")
上述语句中的字符串是要包含的实体。
选择方法:
public virtual TEntity SelectFor(Expression<Func<TEntity, bool>> predicate, bool noTracking = true, bool selectInactiveItems = false, params string[] entitiesToLoad)
{
var query = this.LoadRelatedEntities(this.transaction.Context.Set<TEntity>().AsQueryable(), entitiesToLoad);
query = query.Where(x => x.OwnerId == ownerId).Where(predicate);
if (!selectInactiveItems)
{
query = query.Where(x => x.Active);
}
if (noTracking)
{
query = query.AsNoTracking();
}
return query.FirstOrDefault();
}
包含方法
protected IQueryable<TEntity> LoadRelatedEntities(IQueryable<TEntity> query, params string[] entitiesToLoad)
{
if (entitiesToLoad != null && entitiesToLoad.Count() > 0)
{
foreach (var entityToLoad in entitiesToLoad)
{
query = query.Include(entityToLoad);
}
}
return query;
}
这似乎很容易做,但这需要我的时间和耐心。
答案 0 :(得分:3)
您在查询中使用AsNoTracking
。因此,EF不会跟踪它实现的实体。这意味着当它从数据库中获取Scope
时,它将为每个&#34;相同的&#34;创建多个对象。范围。这肯定发生在这里,因为循环查询模式Scope.Hiring.Scopes
。
但是,EF 在构建对象图时执行关系修正,即它使用实体化的实体填充导航属性,以便f.e.每个Scope
对象都有一个Hiring
引用。执行此操作时,我认为它会尝试将重复的Scope
对象分配给已具有此对象的Hiring
对象。
解决方案:移除AsNoTracking
或删除循环查询:Scope.Hiring
而不是Scope.Hiring.Scopes
。