[英]What's the fastest way to get an ObjectContext reference from an entity object?
我正在为我的EntityFramework对象创建扩展,如如何:自定义生成的数据对象中所述,但在某些扩展中,我需要获取实例的ObjectContext来查找模型中的其他值。 我已经找到了提示24 - 如何从实体获取ObjectContext,但这是几年前编写的,这在类似的SO问题中被引用,但我真的希望现在有更好的答案。
当然,这必须是经常需要的东西,以便使用官方方法支持从实体本身检索实体的对象上下文。
提前感谢您提供有关此实施的最新信息。
还有另一种解决方案,使用连接属性 。
使用连接属性将如下所示(警告:未经测试的代码):
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上实现Active Record Pattern的情况下有所帮助,但在这种情况下,您可能还可以控制在实体的静态方法中创建上下文,这样您就可以将其设置为实体。 在其他情况下,我会说这是你应该尽可能避免的事情。
这是我用的; 它是一种基于约定的方法,可以很容易地添加到项目中。
首先,在对象上下文中添加钩子:
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
属性添加到每个实体类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.