Какой самый быстрый способ получить ссылку ObjectContext от объекта сущности? - PullRequest
5 голосов
/ 18 апреля 2011

Я создаю расширения для своих объектов EntityFramework, как описано в Как: настроить сгенерированные объекты данных , но в некоторых из этих расширений мне нужно получить ObjectContext экземпляра для поиска других значений в модели,Я нашел Совет 24 - Как получить ObjectContext от сущности , но это было написано пару лет назад, на которое есть ссылка в этом подобном SO вопросе , но я действительно надеюсьтеперь есть лучший ответ.

Конечно, это должно быть достаточно часто, чтобы извлечение контекста объекта сущности из самой сущности должно было поддерживаться официальным методом.

Заранее спасибо заболее свежая информация об этой реализации.

Ответы [ 3 ]

3 голосов
/ 22 апреля 2011

Существует другое решение, использующее связанных свойств .

Использование связанных свойств будет выглядеть следующим образом (предупреждение: непроверенный код):

public partial class Database1Entities
{
    private struct ObjectContextProperty { }

    partial void OnContextCreated()
    {
        this.ObjectMaterialized += (_, e) =>
        {
            e.Entity.GetConnectedProperty<Database1Entities, ObjectContextProperty>().Set(this);
        };
        this.ObjectStateManager.ObjectStateManagerChanged += (_, e) =>
        {
            if (e.Action == CollectionChangeAction.Add)
            {
                e.Element.GetConnectedProperty<Database1Entities, ObjectContextProperty>().Set(this);
            }
            else if (e.Action == CollectionChangeAction.Remove)
            {
                e.Element.GetConnectedProperty<Database1Entities, ObjectContextProperty>().Set(null);
            }
        };
    }

    /// <summary>
    /// Gets the object context for the entity. Returns <c>null</c> if the entity is detached.
    /// </summary>
    /// <param name="entity">The entity for which to return the object context.</param>
    public static Database1Entities FromEntity(EntityObject entity)
    {
        return entity.GetConnectedProperty<Database1Entities, ObjectContextProperty>().GetOrConnect(null);
    }
}

Затем вы можете использовать Database1Entities.FromEntity, чтобы получить контекст объекта от объекта-сущности. Вы также можете определить фактическое свойство для объектов сущности, если хотите:

public partial class Table1
{
    /// <summary> 
    /// Gets the object context for this entity. Returns <c>null</c> if the entity is detached.
    /// </summary> 
    public Database1Entities ObjectContext { get { return Database1Entities.FromEntity(this); } }
}

В этом решении свойство ObjectContext объектов сущности является необязательным.

0 голосов
/ 22 апреля 2011

Это то, что я использую; это основанный на соглашении подход, который просто добавить в проект.

Сначала добавьте хуки в контекст вашего объекта:

public partial class Database1Entities
{
    partial void OnContextCreated()
    {
        this.ObjectMaterialized += (_, e) =>
        {
            try
            {
                dynamic entity = e.Entity;
                entity.ObjectContext = this;
            }
            catch (RuntimeBinderException)
            {
            }
        };
        this.ObjectStateManager.ObjectStateManagerChanged += (_, e) =>
        {
            if (e.Action == CollectionChangeAction.Add)
            {
                try
                {
                    dynamic entity = e.Element;
                    entity.ObjectContext = this;
                }
                catch (RuntimeBinderException)
                {
                }
            }
            else if (e.Action == CollectionChangeAction.Remove)
            {
                try
                {
                    dynamic entity = e.Element;
                    entity.ObjectContext = null;
                }
                catch (RuntimeBinderException)
                {
                }
            }
        };
    }
}

Это попытается динамически установить свойство с именем ObjectContext для любого объекта, связанного с контекстом объекта.

Затем добавьте ObjectContext к типам сущностей:

public partial class Table1
{
    /// <summary> 
    /// Gets or sets the context for this entity.
    /// This should not be set by end-user code; this property will be set
    /// automatically as entities are created or added,
    /// and will be set to <c>null</c> as entities are detached.
    /// </summary> 
    public Database1Entities ObjectContext { get; set; }
}

Это решение требует добавления свойства ObjectContext к каждому типу сущности.

0 голосов
/ 18 апреля 2011

Нет, такого метода нет. Описанный обходной путь выглядит как единственный вариант, поскольку сущность является производной от EntityObject, который определяется как:

[Serializable, DataContract(IsReference=true)]
public abstract class EntityObject : StructuralObject, IEntityWithKey,  
    IEntityWithChangeTracker, IEntityWithRelationships
{
    ...
}

Как я знаю только IEntityWithRelationships.RelationshipManager приводит к ObjectContext. Это не изменилось в EF 4.

Кроме того, на самом деле не распространен доступ к контексту от сущности. Я могу себе представить, что это может быть полезно в случае реализации Active Record Pattern поверх EF, но в этом случае вы, вероятно, также можете контролировать создание контекста внутри статического метода объекта, поэтому вы сможете установить его на юридическое лицо. В других случаях я бы сказал, что вам следует избегать этого как можно больше.

...