【问题标题】:Add multiple relational data into SQL server using EF core使用 EF 核心将多个关系数据添加到 SQL Server
【发布时间】:2021-12-03 07:54:43
【问题描述】:

我正在尝试使用 EF core 5 将多个关系数据插入 SQL Server DB。 我想插入多个父母和多个孩子。父母和孩子是一对多的关系。我正在尝试使用 context.AddRang(lstparents) 它仅为一个父母插入子实体数据,而其他父母则没有条目。你能帮我解决这个问题吗?

我的模特

    Public class Parent
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      Public int64 Id {get; set;}// this is identity column
    
      Public string Name { get; set;}
    
      Public List<Child> child { get; set;}
    }

    Public class Child
    {
       [Key]
       [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
       Public int64 id { get; set;} // identity column
       Public string ChildName { get; set;}
    
       Public int64 ParentId { get; set;}
    
       [Foreign key("ParentId")]
       Public Parent parent { get; set;}
    }


// Here is insertion logic

Public void main(string[] args)
{

List<Child> lstChild = new List<Child> () 
                      { 
                        new Child{ ChildName= "Child1Name"}, 
                        new Child{ ChildName= "Child2Name"}, 
                        new Child{ ChildName= "Child3Name"} 
                      }; 
List<Parent> lstparents = new List<Parent>()
                       { 
                        new Parent {Name = "xyz", Child= lstChild }, 
                        new Parent {Name = "xyz1", Child= lstChild} 
                       };
Context.AddRangeAsync(lstparents); 
Context.SaveChangesAsync();


}

我也尝试了以下选项,但遇到了另一个问题。

选项 1:

Public void main(string[] args)
    {
    
    List<Child> lstChild = new List<Child> () 
                          { 
                            new Child{ ChildName= "Child1Name"}, 
                            new Child{ ChildName= "Child2Name"}, 
                            new Child{ ChildName= "Child3Name"} 
                          }; 
    List<Parent> lstparents = new List<Parent>()
                           { 
                            new Parent {Name = "xyz", Child= lstChild }, 
                            new Parent {Name = "xyz1", Child= lstChild} 
                           };
    foreach(var item in lstparents)
    {
        Context.Add(item); 
        foreach(var child in lstChild)
        {
            Context.Add(child); 
         }
     }
     Context.SaveChangesAsync();   
    }

选项2: 在下面的代码行中,我收到一个错误 “当 IDENTITY_INSERT 设置为 OFF 时,无法为表中的标识列插入显式值”

Public void main(string[] args) {

    List<Child> lstChild = new List<Child> () 
                          { 
                            new Child{ ChildName= "Child1Name"}, 
                            new Child{ ChildName= "Child2Name"}, 
                            new Child{ ChildName= "Child3Name"} 
                          }; 
    List<Parent> lstparents = new List<Parent>()
                           { 
                            new Parent {Name = "xyz", Child= lstChild }, 
                            new Parent {Name = "xyz1", Child= lstChild} 
                           };
    foreach(var item in lstparents)
    {
        Context.Entry(item).State=EntityState.Added; 
        foreach(var child in lstChild)
        {
            Context.Entry(child).State=EntityState.Added; 
         }
     }
     Context.SaveChangesAsync();   
    }

【问题讨论】:

    标签: c# .net-core entity-framework-core facebook-c#-sdk


    【解决方案1】:

    由于您有一对多的关系(一个父母可以有多个孩子),您不能将一个孩子集添加到多个父母。如果需要,需要配置多对多关系。因此,如果您想添加 2 个父母,则必须创建 2 个孩子列表,而不是一个

    List<Child> childList1 = new List<Child> () 
                          { 
                            new Child{ ChildName= "Child1Name"}, 
                            new Child{ ChildName= "Child2Name"}, 
                            new Child{ ChildName= "Child3Name"} 
                          }; 
    List<Child> childList2 = new List<Child> () 
                          { 
                            new Child{ ChildName= "Child4Name"}, 
                            new Child{ ChildName= "Child5Name"}, 
                            new Child{ ChildName= "Child6Name"} 
                          }; 
    List<Parent> lstparents = new List<Parent>()
                           { 
                            new Parent {Name = "parent1", Child= childList1 }, 
                            new Parent {Name = "parent2", Child= childList2 } 
                           };
    

    由于你的 main 不是异步的,你只能使用同步操作

    Context.AddRange(lstparents); 
    Context.SaveChanges();
    

    恕我直言,让 ParentId 可以为空可能是个好主意

     public long? ParentId { get; set;}
    

    如果您需要添加多对多,则需要添加 ParentChild 表。

    如果你使用net5+,ef core可以为你添加,你只需要改变navigaion属性

     Public class Parent
        {
            [Key]
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
          public long Id {get; set;}// this is identity column
        
          public string Name { get; set;}
        
          public virtual ICollection<Child> Childs { get; set;}
        }
    
        Public class Child
        {
           [Key]
           [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
           public long Id { get; set;} // identity column
           public string ChildName { get; set;}
              
           public virtual ICollecton<Parent> Parents { get; set;}
        }
    

    【讨论】:

    • 正如你所说的,我需要一个父母和多个孩子。就我而言,我想将具有不同主键的相同子级添加到不同的父级。我的子列表将是相同的,但在插入数据库时​​,每个父级都有不同的主键。我们可以在 EF Core 中做到这一点吗?
    • @user1776386 我更新了我的答案。在此之后,您将不得不再次干净迁移到 Db。
    • @user1776386 "我想将 same 具有 different 主键的子级添加到不同的父级" 他们是 不 如果 PK(实体身份)不同,则相同。具有相同的名称和其他属性不会使它们相同。使用 分离 对象和列表,如答案开头的 Serge 所示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    相关资源
    最近更新 更多