c# - Entity Framework - 包含/引用/集合

标签 c# entity-framework navigation-properties

我想知道为什么有单独的方法来填充导航属性。

如果我处理整个集合,我可以对属性或集合调用 Include

但是,如果我处理单个实体,则有两个单独的方法可以调用,具体取决于项目是集合 (Collection) 还是单个引用 (Reference ).

有没有办法解决这个问题 - 这让事情变得比我认为必要的更复杂。谁能解释为什么在设计 EF 时决定这样做?

编辑

再往下看,问题就更深了。我试图做的是创建一种通用方法来在单个实体上加载集合/导航属性。这可以使用 Include 在整个集合上很容易地完成。但是 ReferenceCollection 的方法签名略有不同。

没关系,必须将这些调用分散到我的应用中。

例如

dbSet<T>().Include(e => e.Property).Include(e => e.Collection).Include(e => e.Collection.Property) 

一切似乎都有效。

但是对单个实体的调用是不同的:

context.Entry(entity).Reference(e => e.Property).Load();
context.Entry(entity).Reference(e => e.Property.Select(e => e.SubProperty)).Load();
context.Entry(entity).Collection(e => e.Collection).Load();

最佳答案

Include() 方法的唯一目的是在查询时显式地急切加载相关数据。

另一方面,Entry() 方法旨在让您对附加到上下文的实体的当前状态进行特定控制,而不仅仅是 Load()相关数据。

这就是为什么您必须在 CollectionReferenceProperty 方法之间明确选择的原因,每个方法都公开不同的功能集(因此返回不同的类型)。

例如:

  • Scalar (DbPropertyEntry) 包含 IsModified 属性,表示值是否从“x”更改为“y”(例如)。

  • Reference (DbReferenceEntry) 包含 IsLoaded 属性,表示引用的数据是否已经从数据库加载。

  • Reference Collection (DbCollectionEntry) 派生自 ICollection(因此也是 IEnumerable)这意味着你可以迭代它的数据。但是,它不能包含 IsModified 属性,因为它可能因集合中的每个项目而异。

不过,如果您只对 Load() 感兴趣,您可以利用多态的 Member() 方法(返回 DbMemberEntry这是所有上述类型的基本类型)并检查条目是否为“可加载”:

var memberEntry = this.Entry(entity).Member("NavigationProperty");

if (memberEntry is DbCollectionEntry collectionMember)
    collectionMember.Load();

if (memberEntry is DbReferenceEntry referenceMember)
    referenceMember.Load();

关于c# - Entity Framework - 包含/引用/集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18072243/

相关文章:

c# - 初始化 ThreadStatic 字段仍然导致 NullReferenceException

c# - 强制 TextBox 刷新

c# - WPF 对网格中的单个行列使用 GridSplitter

c# - virtual 关键字对 Entity Framework 5 中的实体属性有什么影响?

crash - 添加具有导航属性的实体对象作为数据源,导致 Visual Studio 2015 崩溃

c# - 如何取消订阅此 .NET 事件?

c# - ObjectContext.ExecuteStoreCommand,如何在调用之间清除参数?

c# - EF有时可以在成功写入后重试吗?

c# - 在 Entity Framework 中为子列表加入 vs 导航属性

entity-framework - 如何在View中获取IdentityUser角色的名称?