Reputation: 15742
I need to find out, whether the owner of a given EntityCollection<T>
is detached from the Context or not. The reason is to avoid failing subsequent Load() calls to the collection. However, the _owner
and _wrappedOwner
field of the collection is not accessible, and none of the available metadata seems to provide this information.
Is there a way to find out the owner (or at least it's EntityState)?
Context: Since we are not allowed, by policy, to use lazy loading, I want to create some easy explicit late loading when needed, preferably using a generic method. This is how I do it currently, asking for the owner as parameter:
public static EntityCollection<T> ReloadIfNeeded<T>(this EntityCollection<T> collection, EntityObject owner) where T : EntityObject {
if (owner.EntityState != EntityState.Detached && !collection.IsLoaded) {
collection.Load();
}
return collection;
}
Example call:
var orders = customer.Orders.ReloadIfNeeded(customer); //I would like to get rid of the customer parameter here...
I am using .NET Version 4.0.
EDIT: My solution, implementing the answer by Ognyan Dimitrov:
public static EntityCollection<T> ReloadIfNeeded<T>(this EntityCollection<T> collection) where T : EntityObject {
try {
if (!collection.IsLoaded) {
collection.Load();
}
} catch (InvalidOperationException) {
//just leave unloaded
}
return collection;
}
This does not consider the entity state, as originally sought after, but gets rid of the unwanted parameter in expense of a try/catch clause.
Upvotes: 2
Views: 174
Reputation: 6273
Combing the EntityCollection with Reflector and looking at the code I see that this class has a public method
public override void Load(MergeOption mergeOption)
{
base.CheckOwnerNull();
this.Load(null, mergeOption);
}
which then calls another internal Load method :
internal void Load(List<IEntityWrapper> collection, MergeOption mergeOption)
{
bool flag;
ObjectQuery<TEntity> query = base.ValidateLoad<TEntity>(mergeOption, "EntityCollection", out flag);
base._suppressEvents = true;
try
{
if (collection == null)
{
base.Merge<TEntity>(flag ? RelatedEnd.GetResults<TEntity>(query) : Enumerable.Empty<TEntity>(), mergeOption, true);
}
else
{
base.Merge<TEntity>(collection, mergeOption, true);
}
}
finally
{
base._suppressEvents = false;
}
this.OnAssociationChanged(CollectionChangeAction.Refresh, null);
}
It looks like that it checks internally if the owner is there which will save you from 'failing subsequent Load()' if you catch the exception. If you call Load(MergeOption) with MergeOption in any moment you specify.
Does 'Detached' in your case means that the Entity has just came from the front end from a POST request? If you have previous access to the parent entity you can check its state with :
_context.Entry(entity).State
I do not know if detaching the parent Entity will reflect in setting the 'state' of the children to the same state.
Upvotes: 2