【问题标题】:Why child entites binds to parent automatically in entity framework为什么子实体在实体框架中自动绑定到父实体
【发布时间】:2016-04-07 13:17:06
【问题描述】:

我不知道这是好事还是坏事以及如何适应它。

亲子关系非常简单明了。没什么大不了的。可以看下面的代码:

父对象:

public class Parent
{
    public int Id {get;set;}
    public List<Child> Childs {get;set;}
}

子对象

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();

当我运行上面的代码时,我期望 parent 对象具有 Childs 属性是 nullchildCollection 具有 null Parent 属性。但这并没有发生。执行第二行代码后,parent.Childs 填充子对象,并且子对象中的每个Parent 属性都等于parent,这是我不想要的(我应该想要它吗?)。

为什么 entityframework 会这样?我应该注意哪些情况?如果我在不知道这种行为的情况下更改 childCollection 会发生什么?

【问题讨论】:

    标签: c# entity-framework entity-framework-6


    【解决方案1】:

    是的,这是 EF 的正常行为。在childCollection 被具体化调用ToList 的那一刻,当您再次检查parent 实例时,将运行关系修复并检查其FK 与您当前parent 的PK 值相同的Child 实体已在对象上下文中较早加载。如果是这种情况,Parent.Childs 属性将立即与那些Child 实体一起设置。这与延迟加载无关,实际上您的模型不满足延迟加载需要的所有requirements,例如您的导航属性应该是virtual

    此行为无法禁用,但如果您当时使用AsNoTracking 扩展方法来构建查询,则返回的实体不会缓存在DbContext 中:

    var query= context.Childs.AsNoTracking().Where(c=>c.ParentId==10);
    

    您还可以在这个优秀的post中找到更多详细信息

    【讨论】:

    • 太棒了。我得到了它。 AsNoTrackin() 选项将挽救我的生命。谢谢。
    【解决方案2】:

    与许多现代 ORM 一样,Entity Framework 不仅旨在将您的查询结果映射到实体(对象),还将它们的关系映射到属性。如果您声明一个导航属性(例如您在类中使用ChildsParent 属性),EF 将(懒惰地)将这些属性自动映射到它们引用的实体(您可以找到更多关于导航属性here)。

    此行为是设计使然,旨在避免使用联接显式执行查询,并且无需调用childRepository.FindAll(x=&gt; ...,因为只要您访问Childs 属性,EF 就会加载所有相关的Child 实体在您的 Parent 对象中。

    还请记住,EF 实现了更改跟踪系统,因此如果您修改从数据库中获取的实体,EF 将跟踪这些更改并在您第一次在上下文中调用 SaveChanges 时将它们持久化。

    附带说明,EF 架构实际上是 UnitOfWork 和 Repository 模式一起使用的一个示例(DbContext 是一个 UoW,每个 DbSet 都像一个 Repository 一样工作),所以我强烈建议您阅读有关 EF 的更多信息以避免误用它功能或使用其他抽象(例如您的存储库)自己重新实现它们。

    【讨论】:

    • 感谢您的回答。但是有一个问题,重新实施是什么意思?存储库模式与实体框架广泛使用?
    猜你喜欢
    • 2015-06-21
    • 2022-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多