我想知道为什么有单独的方法来填充导航属性。
如果我处理整个集合,我可以对属性或集合调用 Include
。
但是,如果我处理单个实体,则有两个单独的方法可以调用,具体取决于项目是集合 (Collection
) 还是单个引用 (Reference
).
有没有办法解决这个问题 - 这让事情变得比我认为必要的更复杂。谁能解释为什么在设计 EF 时决定这样做?
编辑
再往下看,问题就更深了。我试图做的是创建一种通用方法来在单个实体上加载集合/导航属性。这可以使用 Include 在整个集合上很容易地完成。但是 Reference
和 Collection
的方法签名略有不同。
没关系,必须将这些调用分散到我的应用中。
例如
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()
相关数据。
这就是为什么您必须在 Collection
、Reference
和 Property
方法之间明确选择的原因,每个方法都公开不同的功能集(因此返回不同的类型)。
例如:
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/