简体   繁体   中英

Add multiple relational data into SQL server using EF core

I am trying to insert multiple relational data into SQL server DB using EF core 5. I want to insert multiple parents with multiple child. Parents and child has one to many relationship. I am trying to add it using context.AddRang(lstparents) It is inserting child entity data only for one parents and for rest of the parents there is no entry. Could you please help me to resolve this issue.

My Models

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


}

I have tried below options as well but I ran into another problem.

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

option2: In below line of code i am getting an error "Cannot insert explicit value for identity column in table when IDENTITY_INSERT is set to 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();   
    }

Since you have one-to-many relations (one parent can have many children) you can't add one child set to many parents. If you neeed it , you need to configure many-to-many relations. So if you want to add 2 parents you will have to create 2 lists of children, not one

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 } 
                       };

and since your main is not async you can only use sync operations

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

and IMHO maybe it is a good idea to make ParentId nullable

 public long? ParentId { get; set;}

and if you need to add many to many you need to add a ParentChild table.

If you use net5+ , ef core can add it for you , you just need to change navigaion properties

 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;}
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM