[英]Refreshing lazy loaded relationships in Entity Framework
我试图找到一种方法来刷新我的EF实体后,他们被另一个上下文修改。 除导航属性外,一切正常,但未更新。
改变后我尝试了两个:
var objectContext = ((IObjectContextAdapter)context).ObjectContext;
objectContext.Refresh(RefreshMode.ClientWins, entity);
和:
context.Entry(entity).Reload();
但两者都不会导致关系更新。 这是代码优先模型(删除了一些东西):
public class ElementType : IElementType
{
[Key]
public Guid ID { get; set; } = Guid.NewGuid();
public virtual List<Element> Elements { get; set; }
}
public class ElementType : IElementType
{
[Key]
public Guid ID { get; set; } = Guid.NewGuid();
public virtual ElementType ElementType { get; set; }
}
我正在添加一个新元素,并且刷新不会更新ElementType中的Elements关系属性。 我知道事情正在被其他上下文更新,因为当我关闭所有内容并重新启动它时,everthing看起来就像我期望的那样。
上下文仍然是连接的,因为我可以从DB上下文中获取新实体。 我甚至可以通过导航到新元素,检查它的关系属性(然后触发ElementType更新)来强制ElementType在调试器中更新它的Element集合:
如果我导航到调试器中的上下文,请检查元素集,新元素是否存在,以及关系属性是否设置正确(并引用相同的Proxy ElementType对象)。 所以这是DBContext的Elements集合:
现在回到原始元素:
一切都是最新的!
所以我很确定一切正常,除了刷新/更新方法。 这里的问题表明Reload应该适用于延迟加载的关系,我似乎无法找到有关如何实际刷新此集合的任何进一步信息。 任何人都知道为什么它没有像我期望的那样工作?
感谢Cristian Szpisjak将我指向了DbEntityEntry的Collection方法。
我写了一个用于刷新我的集合的通用方法:
public void Refresh(object entity)
{
DbEntityEntry entry = context.Entry(entity);
entry.Reload();
var values = entity.GetType().BaseType
.GetProperties()
.Where(propertyInfo => propertyInfo.GetCustomAttributes(typeof(ReloadCollectionOnRefresh), false).Count() > 0)
.Select(propertyInfo => propertyInfo.Name);
foreach (string value in values)
{
var collection = entry.Collection(value);
collection?.Load();
}
}
使用ReloadCollectionOnRefresh自定义属性标记集合属性的位置:
[ReloadCollectionOnRefresh]
public virtual List<MyEntity> MyEntities{ get; set; }
这只是一个非常空的属性来'标记'集合:
[AttributeUsage(AttributeTargets.Property)]
class ReloadCollectionOnRefresh : Attribute
{
// can we add checking that this is applied to a virtual collection?
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.