C# EF 5代码优先-为什么显式加载的数据无法从我的模型访问?
我有以下两个具有多对多关系的模型对象:C# EF 5代码优先-为什么显式加载的数据无法从我的模型访问?,c#,entity-framework,C#,Entity Framework,我有以下两个具有多对多关系的模型对象: public class StaffMember { public Guid StaffMemberKey {get; set;} // lots of other properties that aren't relevant public ICollection<Case> Cases {get; set;} } public class Case { public int CaseKey {get; s
public class StaffMember
{
public Guid StaffMemberKey {get; set;}
// lots of other properties that aren't relevant
public ICollection<Case> Cases {get; set;}
}
public class Case
{
public int CaseKey {get; set;}
// lots of other properties that aren't relevant
public ICollection<StaffMember> Staff {get; set;}
}
我希望selectedCase.Staff
将包含加载的工作人员,但它仍然为空。如果在查询相关数据时调用ToList()
而不是Load
,则生成的列表确实包含正确的工作人员实体。如果我只是调用context.Entry(selectedCase.Collection)(c=>c.Staff.Load()代码>,然后按预期加载数据。有什么我遗漏的吗?有什么好处
最后一点要注意的是,我已经为我的上下文禁用了延迟加载和代理创建,以防在这种情况下产生任何差异。当您调用Query()
时,它会返回一个IQueryable
,它给出了该属性中的实体——它不是用来更新该属性的。这基本上是一条“捷径”:
Load()
将实体加载到您的上下文中,就像您调用了ToList()
但没有返回任何内容一样。它适用于任何IQueryable
,不捕获与Entry()
相关的任何内容。查询()的结果将返回,而不是插入到集合中。是的,但我正在对IQueryable
结果调用.Load()
,该结果应将结果实体加载到上下文中。根据我的理解,这应该使它们在我的模型上可用,但也许这只适用于一对多关系,而不是多对多关系。我正在遵循从MSDN到T的示例,或者尝试无论如何……它将对象加载到EF上下文中,但不加载到属性中。@CoryNelson:我知道它将对象加载到上下文中,但不填充集合。然而,我试图理解为什么会这样,这是正常行为还是错误,或者我是否做了一些不正确的事情。我可以在一对多关系中做一些非常类似的事情,它似乎非常有效。您的集合属性不是虚拟的。问题是,按照我在OP中描述的方式加载相关实体对于一对多关系非常有效。例如,我有一个公司
实体,它与员工有一对多的关系。我可以调用ctx.Entry(company).Collection(c=>c.Staff).Query().Where(sm=>sm.StaffMemberKey==someKeyValue).Load()代码>和加载的工作人员可通过company.staff
访问。只是对于多对多关系来说,它似乎并没有按照我期望的方式工作。当MS提供了明确说明如何准确执行我尝试执行的操作()的文档时,你怎么能说EF不是这样设计的呢?如前所述,它也适用于一对多关系DbCollectionEntry.Load
和IQueryable.Load
是两种做不同事情的不同方法。我想这就是你感到困惑的地方。他们的文档中没有说明通过执行Query().Load()
调用的IQueryable.Load()
,将填充属性。如果你能为一对多的关系提供代码,而这种关系表现出相反的行为,我很想看看。
public class CaseMapping : EntityTypeConfiguration<Case>
{
public CaseMapping()
{
// other property and relationship mappings
// Many-to-Many mapping with Staff Members
HasMany(c => c.Staff)
.WithMany(staffMember => staffMember.Cases)
.Map(m =>
{
m.ToTable("Cases_StaffMembers", "dbo");
m.MapLeftKey("CaseKey");
m.MapRightKey("StaffMemberKey");
});
}
}
var staffMemberKey = Guid.Parse("...");
var caseKey = 5;
using (var context = new CodeFirstContext())
{
var selectedCase = context.Cases.Find(caseKey);
context.Entry(selectedCase).Collection(c => c.Staff).Query().Where(sm => sm.StaffMemberKey == staffMemberKey).Load();
}
ctx.Staff.Where(staff => staff.Case.Id == caseKey);