Sim*_*mon 8 c# entity-framework navigation-properties
我想知道为什么有单独的方法来填充导航属性.
如果我在整套工作,我可以打电话Include给财产或集合.
但是,如果我处理单个实体,则根据项目是collection(Collection)还是单引用(Reference),有两种不同的方法可以调用.
有没有办法解决这个问题 - 这使得事情变得比我想象的更复杂.谁能解释为什么在设计EF时决定了这一点?
编辑
进一步研究,问题更深入.我试图做的是创建一种在单个实体上加载集合/导航属性的通用方法.使用Include可以在整个集合上轻松完成.但该方法的签名Reference和Collection略有不同.
没关系,将不得不在我的应用程序周围分散这些调用.
例如
dbSet<T>().Include(e => e.Property).Include(e => e.Collection).Include(e => e.Collection.Property)
Run Code Online (Sandbox Code Playgroud)
一切似乎都有效.
但是,对单个实体的调用是不同的:
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();
Run Code Online (Sandbox Code Playgroud)
hai*_*770 13
该Include()方法的唯一目的是在查询时明确地急切加载相关数据.
Entry()另一方面,该方法旨在为您提供对附加到上下文的实体的当前状态的具体控制,而不仅仅是Load()相关数据.
这就是为什么你必须明确地之间选择的原因Collection,Reference和Property方法,每一个公开组不同的功能(因此返回不同的类型),例如:
Scalar(DbPropertyEntry)包含IsModified表示值是否从"x"更改为"y"(例如)的属性.
Reference(DbReferenceEntry)包含IsLoaded表示数据是否已从数据库加载的属性(与'Scalar'属性条目相对).
Reference Collection(DbCollectionEntry)派生自ICollection(因此IEnumberable也是),这意味着您可以迭代它的数据.但是,它不能包含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();
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
1.-加载包含集合的实体:
MyClass myObject = dbContext.MyClasses
.Include(cls => cls.ObjectCollection)
.Single(cls => cls.Pk == entityPk);
Run Code Online (Sandbox Code Playgroud)
2.-然后,您必须检索该对象Entry并告诉EF在集合对象中加载所需的属性:
dbContext.Entry(myObject).Collection("ObjectCollection").Query().Include("ReferenceClass").Load();
Run Code Online (Sandbox Code Playgroud)
进一步阅读:
http://msdn.microsoft.com/en-us/data/jj574232#explicitFilter