我想知道为什么有单独的方法来填充导航属性。
如果我在整套工作,我可以在一个属性或集合上调用Include
。
但是,如果我处理单个实体,则根据项目是集合(Collection
)还是单个引用(Reference
),有两种不同的方法可以调用。
有没有办法解决这个问题 - 这使得事情变得比我想象的更复杂。有谁可以解释为什么在设计EF时决定了这个?
修改
进一步研究,问题更深入。我试图做的是创建一种在单个实体上加载集合/导航属性的通用方法。使用Include可以在整个集合上轻松完成。但Reference
和Collection
的方法签名略有不同。
没关系,必须在我的应用程序周围分散这些调用。
e.g。
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();
答案 0 :(得分:13)
Include()
方法的唯一目的是在查询时明确地加载相关数据。
另一方面,Entry()
方法旨在让您对附加到上下文的实体的当前状态进行特定控制,而不仅仅是Load()
相关数据。
这就是为什么你必须在Collection
,Reference
和Property
方法之间明确选择的原因,每个方法都暴露不同的功能集(因此返回不同的类型),例如:
标量(DbPropertyEntry
)包含IsModified
属性,表示值是否从&#39; x&#39;到了&#39; (例如)。
参考(DbReferenceEntry
)包含IsLoaded
属性,表示数据是否已从数据库加载(而不是&#39; Scalar& #39;财产进入)。
参考集合(DbCollectionEntry
)派生自ICollection
(因此也IEnumberable
),这意味着您可以对其进行迭代。数据。但是,它不能包含IsModified
属性,因为它可能对集合中的每个项目都有所不同。
但是,如果你只对Load()
感兴趣,你可以利用多态Member()
方法(返回DbMemberEntry
,它是所有上述类的基类)并检查条目是否为“可加载的”
var memberEntry = this.Entry(entity).Member("NavigationProperty");
if (memberEntry is DbCollectionEntry)
((DbCollectionEntry)memberEntry).Load();
if (memberEntry is DbReferenceEntry)
((DbReferenceEntry)memberEntry).Load();
答案 1 :(得分:5)
你可以这样做:
1.-加载包含馆藏的实体:
MyClass myObject = dbContext.MyClasses
.Include(cls => cls.ObjectCollection)
.Single(cls => cls.Pk == entityPk);
2.-然后您必须检索该对象Entry并告诉EF在集合对象中加载所需的属性:
dbContext.Entry(myObject).Collection("ObjectCollection").Query().Include("ReferenceClass").Load();
进一步阅读:
http://msdn.microsoft.com/en-us/data/jj574232#explicitFilter
答案 2 :(得分:0)
您还可以使用Select加载引用的集合。
db.MyObject.Include(x => x.RefObect.Select(y => y.RefRefObject));