简体   繁体   English

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

[英]What's the fastest way to get an ObjectContext reference from an entity object?

I'm creating extensions for my EntityFramework objects as described in How to: Customize Generated Data Objects but in some of those extensions I need to get the instance's ObjectContext to look up some other values in the model. 我正在为我的EntityFramework对象创建扩展,如如何:自定义生成的数据对象中所述,但在某些扩展中,我需要获取实例的ObjectContext来查找模型中的其他值。 I've found Tip 24 – How to get the ObjectContext from an Entity but that was written a couple years ago, which is referenced in this similar SO question but I'm really hoping there's a better answer now. 我已经找到了提示24 - 如何从实体获取ObjectContext,但这是几年前编写的,这在类似的SO问题中被引用,但我真的希望现在有更好的答案。

Surely this must be something that's needed frequently enough that retrieval of an Entity's object context from the entity itself should be supported with an official method. 当然,这必须是经常需要的东西,以便使用官方方法支持从实体本身检索实体的对象上下文。

Thanks in advance for any more recent information on this implementation. 提前感谢您提供有关此实施的最新信息。

There is another solution, using connected properties . 还有另一种解决方案,使用连接属性

Using connected properties would look like this (warning: untested code): 使用连接属性将如下所示(警告:未经测试的代码):

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);
    }
}

Then you can use Database1Entities.FromEntity to get the object context from an entity object. 然后,您可以使用Database1Entities.FromEntity从实体对象获取对象上下文。 You can also define an actual property on the entity objects as well if you want: 如果需要,您还可以在实体对象上定义实际属性:

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); } }
}

In this solution, the ObjectContext property on the entity objects is optional. 在此解决方案中,实体对象上的ObjectContext属性是可选的。

No there is not any such method. 没有没有这样的方法。 The described workaround looks like the only option because the entity is derived from EntityObject which is defined as: 所描述的变通方法看起来是唯一的选项,因为实体派生自EntityObject ,定义为:

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

As I know only IEntityWithRelationships.RelationshipManager leads to ObjectContext . 据我所知,只有IEntityWithRelationships.RelationshipManager会导致ObjectContext This wasn't changed in EF 4. 这在EF 4中没有改变。

Also it is not really common to access the context from the entity. 此外,从实体访问上下文并不常见。 I can imagine that this can be helpful in case of implementing Active Record Pattern on top of EF but in such case you would also have probably control over creating the context inside the static method of the entity so you should be able to set it to the entity. 我可以想象,这可以在EF上实现Active Record Pattern的情况下有所帮助,但在这种情况下,您可能还可以控制在实体的静态方法中创建上下文,这样您就可以将其设置为实体。 In other cases I would say that it is something you should avoid as much as possible. 在其他情况下,我会说这是你应该尽可能避免的事情。

This is what I use; 这是我用的; it's a convention-based approach that is simple to add to a project. 它是一种基于约定的方法,可以很容易地添加到项目中。

First, add hooks to your object context: 首先,在对象上下文中添加钩子:

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)
                {
                }
            }
        };
    }
}

This will attempt to dynamically set a property called ObjectContext on any entity that is associated with the object context. 这将尝试在与对象上下文关联的任何实体上动态设置名为ObjectContext的属性。

Next, add an ObjectContext to the entity types: 接下来,将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; }
}

This solution does require an ObjectContext property to be added to each entity type. 此解决方案确实需要将ObjectContext属性添加到每个实体类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM