I am strugling to understand why the query is retuning this error when I perform the following statement:
SelectFor(x => x.Id == id, true, false, "Scope.Hiring.Scopes")
The string in the above statement are the entities to include.
SelectFor Method:
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();
}
Include Method
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;
}
It seems quite easy thing to do, but it's taking my time and patience.
You use AsNoTracking in your query. Because of this, EF doesn't keep track of the entities it materializes. This means that when it fetches Scopes from the database it will create multiple objects for each "identical" scope. This definitely happens here because of the circular query pattern Scope.Hiring.Scopes.
However, EF does perform relationship fixup while building the object graph, i.e. it populates navigation properties with entities that are materialized so that f.e. each Scope object will have a Hiring reference. While doing this, I figure it tries to assign a duplicated Scope object to a Hiring object that already has this object.
Solution: remove the AsNoTracking or remove the circular query: Scope.Hiring instead of Scope.Hiring.Scopes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With