从实体对象获取ObjectContext引用的最快方法是什么?

本文关键字:方法 是什么 引用 实体 对象 获取 ObjectContext | 更新日期: 2023-09-27 17:50:34

我正在为我的EntityFramework对象创建扩展,如如何:自定义生成的数据对象中所述,但在一些扩展中,我需要获得实例的ObjectContext来查找模型中的一些其他值。我已经找到了技巧24 -如何从实体中获得ObjectContext,但那是几年前写的,在这个类似的问题中引用,但我真的希望现在有一个更好的答案。

当然,这必须是经常需要的东西,从实体本身检索实体的对象上下文应该有一个正式的方法支持。

提前感谢有关此实现的更多最新信息。

从实体对象获取ObjectContext引用的最快方法是什么?

还有另一种解决方案,使用连接属性。

使用连接属性看起来像这样(警告:未经测试的代码):

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属性是可选的。

不,没有这样的方法。所描述的解决方案看起来是唯一的选择,因为该实体派生自EntityObject,其定义为:

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

据我所知,只有IEntityWithRelationships.RelationshipManager导致ObjectContext。这在EF 4中没有改变。

从实体访问上下文也不是很常见。我可以想象,在EF之上实现活动记录模式的情况下,这可能是有帮助的,但在这种情况下,你也可能控制实体的静态方法中创建上下文,所以你应该能够将其设置为实体。在其他情况下,我会说这是你应该尽可能避免的事情。

这是我使用的;这是一种基于惯例的方法,很容易添加到项目中。

首先,在对象上下文中添加钩子:

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属性。