Учитывая EntityCollection<T>, как узнать, отсоединен ли его владелец или нет?
Мне нужно выяснить, является ли владелец данного EntityCollection<T>
отсоединен от контекста или нет. Причина состоит в том, чтобы избежать сбоя последующих вызовов Load() к коллекции. Тем не менее _owner
а также _wrappedOwner
Поле коллекции недоступно, и ни одна из доступных метаданных, по-видимому, не предоставляет эту информацию.
Есть ли способ узнать владельца (или, по крайней мере, его EntityState)?
Контекст: поскольку по политике мы не можем использовать отложенную загрузку, я хочу создать некоторую простую явную позднюю загрузку, когда это необходимо, предпочтительно с использованием универсального метода. Вот как я делаю это сейчас, спрашивая владельца в качестве параметра:
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;
}
Пример вызова:
var orders = customer.Orders.ReloadIfNeeded(customer); //I would like to get rid of the customer parameter here...
Я использую.NET версии 4.0.
РЕДАКТИРОВАТЬ: Мое решение, реализуя ответ Огнян Димитров:
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;
}
Это не учитывает состояние объекта, как первоначально требовалось, но избавляет от нежелательного параметра за счет предложения try/catch.
1 ответ
Комбинируя EntityCollection с Reflector и глядя на код, я вижу, что у этого класса есть открытый метод
public override void Load(MergeOption mergeOption)
{
base.CheckOwnerNull();
this.Load(null, mergeOption);
}
который затем вызывает другой внутренний метод Load:
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);
}
Похоже, что он проверяет внутренне, есть ли там владелец, что спасет вас от "неудачного последующего Load()", если вы поймаете исключение. Если в любой момент вы укажете Load(MergeOption) с MergeOption.
Означает ли "Отсоединено" в вашем случае, что сущность только что пришла из внешнего интерфейса из запроса POST? Если у вас есть предыдущий доступ к родительскому объекту, вы можете проверить его состояние с помощью:
_context.Entry(entity).State
Я не знаю, отразится ли отстранение родительской сущности от установки "состояния" детей в одно и то же состояние.