C# 为什么子实体在实体框架中自动绑定到父实体
我不知道这是好事还是坏事,也不知道如何适应 亲子关系简单明了,没什么大不了的。您可以看到下面的代码: 父对象: 代码周围的某个地方(比如控制器的索引方法) 当我运行上面的代码时,我希望具有C# 为什么子实体在实体框架中自动绑定到父实体,c#,entity-framework,entity-framework-6,C#,Entity Framework,Entity Framework 6,我不知道这是好事还是坏事,也不知道如何适应 亲子关系简单明了,没什么大不了的。您可以看到下面的代码: 父对象: 代码周围的某个地方(比如控制器的索引方法) 当我运行上面的代码时,我希望具有Childs属性的parent对象是null和具有nullparent属性的childCollection。但这并没有发生。执行第二行代码后,parent.Childs填充子对象,子对象中的每个parent属性都等于我不想要的parent(我应该想要它吗?) 为什么entityframework的行为如此?我应
Childs
属性的parent
对象是null
和具有nullparent
属性的childCollection
。但这并没有发生。执行第二行代码后,parent.Childs
填充子对象,子对象中的每个parent
属性都等于我不想要的parent
(我应该想要它吗?)
为什么entityframework的行为如此?我应该注意哪些情况?如果我在不知道此行为的情况下更改了
子集合
,会发生什么情况?与许多现代ORM一样,Entity Framework的设计目的不仅是将查询结果映射到实体(对象),还将其关系映射到属性。如果您声明了一个导航属性(例如您在类中对Childs
或Parent
属性所做的操作),EF将(惰性地)自动将这些属性映射到其引用的实体(您可以找到有关导航属性的更多信息)
此行为是经过设计的,旨在避免使用联接显式执行查询,并且不必调用childRepository.FindAll(x=>…
),因为只要访问父对象中的Childs
属性,EF就会加载所有相关的Child
实体
还请记住,EF实现了一个更改跟踪系统,因此,如果您修改从数据库中获取的实体,EF将跟踪这些更改,并在您第一次对上下文调用SaveChanges
时将其持久化
作为旁注,EF体系结构实际上是一个UnitOfWork和Repository模式一起使用的示例(DbContext是一个UoW,每个DbSet都像一个Repository),因此我强烈建议您阅读更多关于EF的内容,以避免误用其功能或使用另一个抽象(例如,您的存储库)重新实现它们.是的,这是EF的正常行为。当调用ToList
实现子集合时,当您再次检查父实例时,关系修复程序将运行,并检查其FK值是否与当前父实例的PK值相同的子实体是否已被激活在对象上下文中较早加载。如果是这种情况,将立即使用这些子实体设置Parent.Childs
属性。这与延迟加载无关,事实上,您的模型不能满足所有延迟加载需要,就像您的导航属性应该是virtual
无法禁用此行为,但如果在生成查询时使用扩展方法,则返回的实体将不会缓存在DbContext
:
var query= context.Childs.AsNoTracking().Where(c=>c.ParentId==10);
您还可以在这个优秀的中找到更多详细信息。我知道了。AsNoTrackin()选项将拯救我的生命。谢谢。谢谢您的回答。但有一个问题,您认为重新实现是什么意思?存储库模式广泛用于实体框架?
public class Child
{
public int Id {get;set;}
public int ParentId {get;set;}
public Parent Parent {get;set;}
}
var parent = parentRepository.FindAll(x=> x.Id == 10).ToList();
var childCollection = childRepository.FindAll(x=> x.ParentId == parent.Id).ToList();
var query= context.Childs.AsNoTracking().Where(c=>c.ParentId==10);