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

发布于 2024-11-02 03:35:45 字数 631 浏览 0 评论 0 原文

我正在为 EntityFramework 对象创建扩展,如 如何:自定义生成的数据中所述对象,但在其中一些扩展中,我需要获取实例的 ObjectContext 来查找模型中的一些其他值。我发现 提示 24 – 如何从实体获取 ObjectContext 但这是几年前写的,在此 类似的问题但我真的希望现在有更好的答案。

当然,这一定是经常需要的东西,以至于应该用官方方法支持从实体本身检索实体的对象上下文。

预先感谢有关此实施的任何最新信息。

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. 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.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你爱我像她 2024-11-09 03:35:45

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

使用连接的属性将如下所示(警告:未经测试的代码):

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

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. 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.

杀お生予夺 2024-11-09 03:35:45

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

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

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

而且从实体访问上下文并不常见。我可以想象,这对于在 EF 之上实现 Active Record 模式会很有帮助,但在这种情况下,您可能还可以控制在实体的静态方法内创建上下文,因此您应该能够将其设置为实体。在其他情况下,我会说这是你应该尽可能避免的事情。

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:

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

As I know only IEntityWithRelationships.RelationshipManager leads to ObjectContext. This wasn't changed in 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. In other cases I would say that it is something you should avoid as much as possible.

泼猴你往哪里跑 2024-11-09 03:35:45

这就是我用的;这是一种基于约定的方法,可以轻松添加到项目中。

首先,向对象上下文添加挂钩:

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 属性添加到每个实体类型。

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.

Next, add an ObjectContext to the entity types:

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文