实体框架 6:将子对象添加到父列表与将子对象的导航属性设置为父对象

Posted

技术标签:

【中文标题】实体框架 6:将子对象添加到父列表与将子对象的导航属性设置为父对象【英文标题】:Entity Framework 6: Adding child object to parent's list vs. setting child's navigation property to parent 【发布时间】:2014-09-02 08:14:59 【问题描述】:

我有一个现有的数据库,其中包含两个表 MailServersMailDomainsMailDomains 的外键列 MailServerId 指向 MailServers 中的 Id 主键列。所以我们这里是一对多的关系。

我关注this article,并通过实体数据模型向导中的“数据库代码优先”模型创建了我的实体框架 POCO。这产生了以下两个 C# 类:

public partial class MailServer

    public MailServer()
    
        MailDomains = new HashSet<MailDomain>();
    

    public int Id  get; set; 

    public virtual ICollection<MailDomain> MailDomains  get; set; 




public partial class MailDomain

    public MailDomain()
    
    

    public int Id  get; set; 

    public string DomainName  get; set; 

    public int MailServerId  get; set; 
    public virtual MailServer MailServer  get; set; 

现在我的问题是以下两种在数据库中创建和插入新对象的方法是否有区别。

方法(A):将新子添加到父列表中:

        var mailServer = new MailServer();
        var mailDomain = new MailDomain() 
            DomainName = "foobar.net",
        ;
        mailServer.MailDomains.Add(mailDomain);

        using(var context = new MyContext)
            context.MailServers.Add(mailServer);
            context.SaveChanges();
        

方法(B):将子级的导航属性设置为父级:

        var mailServer = new MailServer();
        var mailDomain = new MailDomain() 
            DomainName = "foobar.net",
            MailServer = mailServer,
        ;

        using(var context = new MyContext)
            context.MailDomains.Add(mailDomain);
            context.SaveChanges();
        

我还假设在方法 (A) 中,新的 MailDomain 实例会自动添加到集合 context.MailDomains 中,而在方法 (B) 中,新的 MailServer 实例会自动添加到集合 context.MailServers 中。这是正确的还是我必须手动执行?

我的问题是:这两种方法可以互换吗? 只是让我感到困惑的是,在数据库中只有一个属性/列需要设置(即MailDomains 中的外键),而在 C# 代码中有两个属性(每个类中一个)可以修改。

【问题讨论】:

【参考方案1】:

是的,这两种方法可以互换。这允许您从 MailServer 或 MailDomain 的角度创建对象图并将其保存到数据库。

如果您执行代码优先,则可以选择删除不需要的属性和映射。

我还假设在方法 (A) 中,新的 MailDomain 实例是 在方法 (B) 中自动添加到 context.MailDomains 新的 MailServer 实例会自动添加到 context.MailServers。 这是正确的还是我必须手动执行?

这取决于您所说的“添加到上下文中”是什么意思。如果你的意思是:当你持久化时它是否会自动保存到数据库中,答案是肯定的。使用像 EF 这样的 ORM 的一大好处是它可以自动处理保存完整的对象图(以及同步 PK/FK 关系等)。

如果您的意思是:实体在保存之前是否可以通过上下文访问,我不这么认为(我不是 100% 确定)。

【讨论】:

以上是关于实体框架 6:将子对象添加到父列表与将子对象的导航属性设置为父对象的主要内容,如果未能解决你的问题,请参考以下文章

将子对象复制到父类型指针中

将子对象从 JSON 绑定到父属性 java

将子实体加载到核心数据中的托管对象

将子组件添加到父组件并将父组件添加到文档

ExtJS/Javascript:将子模型添加到父模型,在网格上呈现

如何将子 ViewController 的视图添加到父 View 控制器的子视图中?