Учитывая 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

Я не знаю, отразится ли отстранение родительской сущности от установки "состояния" детей в одно и то же состояние.

Другие вопросы по тегам