我不确定我是接近错误的方式还是默认行为,但它没有像我期待的那样工作......
以下是两个示例类......
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Department Department { get; set; }
}
第二个是部门
public class Department
{
public string Name { get; set; }
public List<Person> People { get; set; }
}
上下文配置
public MyDbContext() : base("DefaultConnection")
{
this.Configuration.ProxyCreationEnabled = false;
this.Configuration.LazyLoadingEnabled = false;
}
public DbSet<Person> People { get; set; }
public DbSet<Department> Departments { get; set; }
我正在尝试加载名字来自史密斯&#39;
的人var foundPeople
= context
.people
.Where(p => p.LastName == "Smith");
上面的查询加载foundPeople只有FirstName和LastName没有Department对象。这是一个正确的行为,因为我的LazyLoading已关闭。这也是预期的。
现在在另一个带有Eager加载部门的查询中,
var foundPeople
= context
.people
.Where(p => p.LastName == "Smith")
.Include(p => p.Department);
上面的查询加载了带有FirstName,LastName,Department with Department-&gt; Name以及Deparment-&gt; People的人们(该部门的所有人,我不想要,我只想加载Included属性的第一级
我不知道这是预期的行为还是我犯了一些错误。
有没有办法只加载第一级包含的属性,而不是完成图表或所有级别的包含属性。
答案 0 :(得分:3)
使用上启用延迟加载时才有效 - 也就是说,您的导航属性必须声明为Include()
实现预先加载只有在对象virtual
,以便EF代理可以使用延迟加载行为覆盖它们。 否则,他们会急切加载, Include()
将无效。
将 Person.Department
和Department.People
声明为虚拟属性后,您的代码应按预期工作。
非常抱歉,我的原始答案完全不正确。我没有仔细阅读你的问题,事实上对于急切的行为是不正确的。不确定我在想什么(或者是谁投票了?)。真正的答案在下面:
使用您发布的示例模型(进行必要的修改:实体的键并从上下文构造函数中移除&#34; this
&#34;)我无法完全重现你的问题。但是,我不认为它正在按照你的想法去做。
当您急切加载部门(或使用context.Entry(...).Reference(...).Load()
明确加载)时,请更仔细地检查您的结果:Department.People
集合中有元素,但 all 人员,仅查询本身加载的人员。我想你会在最后一个片段中找到!foundPeople.SelectMany(p => p.Department.People).Any(p => p.LastName != "Smith") == true
。也就是说,他们都不是史密斯&#34;。
我认为没有办法解决这个问题。实体框架未明确或急切地加载人员集合(您可以Include(p => p.Department.People)
)。由于模型中的循环关系,它只是将加载到其相关对象的那些链接起来。此外,如果在加载其他人的同一上下文中存在多个查询,则它们也将链接到对象图中。
(旁白:在这种简化的情况下,代理创建和延迟加载配置是多余的 - 由于既没有懒惰或代理能(虚拟)属性,也没有在实体上启用 - 我做的一件事第一次就做对了。)
答案 1 :(得分:2)
通过设计,DbContext
做了所谓的“关系修复”。由于您的模型具有关于您的实体之间关系的信息,因此无论何时附加或修改实体,EF都会尝试“修复”实体之间的关系。
例如,如果在上下文中加载具有FK的实体,该实体指示它是已附加到上下文的另一个实体的子项,则它将被添加到现有实体的子集合中。如果您制作任何字符(更改FK,删除实体等),关系将自动修复。这就是另一个答案所解释的:即使您使用不同的查询分别加载相关实体,它们也会附加到它们所属的子集合中。
无法禁用此功能。请参阅与此相关的其他问题:
如何摆脱相关实体
我不知道您需要做什么,但使用当前版本的EF,您必须detach the entity from the context并手动删除相关实体。
另一种选择是使用AutoMapper或ValueInjecter进行映射,以消除关系修复。
答案 2 :(得分:-2)
您可以尝试使用LINQ查询,以便只选择所需的字段。我希望有所帮助。