2016-06-13 3 views
2

Я пытаюсь вставить родительский объект с n детьми, которые могут дополнительно иметь n своих собственных детей. Когда я вставляю объект, у которого нет внуков, все работает нормально, но как только входной объект содержит внуков, в Context.SaveChanges():Entity framework, вставляющий объект parent-children-grandchildren

«Не удалось выполнить операцию: отношения не могут быть изменены потому что одно или несколько свойств внешнего ключа не имеют значения NULL. При изменении отношения к связанному свойству внешнего ключа установлено значение null. Если внешний ключ не поддерживает нулевые значения, новый должно быть определено отношение, для свойства внешнего ключа должно быть назначено другое ненулевое значение, или не связанный объект должен быть удален ».

Родитель:

public class Parent : Entity 
    { 
     public Parent() 
     { 
      this.Children = new HashSet<Children>(); 
     }   
     public virtual ICollection<Child> Children { get; set; } 
    } 

Ребенок:

public class Child : Entity 
    { 
     public Child() 
     { 
      this.GrandChildren = new HashSet<GrandChild>(); 
     } 
     public virtual ICollection<GrandChild> GrandChildren { get; set; }  
     public int ParentId { get; set; } 
     public virtual Parent Parent { get; set; } 
    } 

Внук:

public class GrandChild : Entity 
    { 
     public int ChildId { get; set; }  
     public virtual Child Child { get; set; } 
    } 

Вот мой DbContext:

modelBuilder.Entity<Child>().ToTable("Children") 
     .HasRequired<Parent>(x => x.Parent); 

    modelBuilder.Entity<GrandChild>().ToTable("GrandChildren") 
     .HasRequired<Child>(y => y.Child); 

    modelBuilder.Entity<Parent>().ToTable("Parents") 
     .HasMany(z => z.Child) 
     .WithRequired(i => i.Parent); 

Затем, наконец, моя вставка выглядит следующим образом. Я создаю новый объект родитель-ребенок-внук, условно основанный на другом объекте ввода (я пытаюсь сохранить исходное состояние вопросника на основе аналогичного объекта вопросника-родителя-ребенка-внука иерархия):

public Parent Insert(List<AnotherObject> input)  
     {     
      Parent parent = new Parent(); 

      // Set parent attributes 
      foreach (var x in input) 
      { 
       Child child = new Child(); 
       // Set child attributes 
       // EDIT: I also set an attribute based on the list of 
       // entities from the input 
       child.OtherObjectId = x.Id; 
       child.Parent = parent;         

       if (x.Children.Count > 0) 
       { 
        foreach (var y in x.Children) 
        { 
         GrandChild grandChild = new GrandChild(); 
         // Set grandChild attributes 

         grandChild.Child = child; 
         child.GrandChildren.Add(grandChild); 
        } 
       } 
       parent.Children.Add(child); 
      } 

      Context.Parents.Add(parent); 
      Context.SaveChanges(); 
     } 

Я проверил БД и юридические лица, в несколько раз, так что я надеюсь, есть какой-то изъян в моей логике вставить вместо этого.

EDIT: Здесь список ввода (выбирается) происходит от в случае, который помогает определить, что-то:

 Random rand = new Random(DateTime.Now.ToString().GetHashCode()); 
     var selected = diffParent.DiffChild.OrderBy(x => rand.Next()).Take(diffParent.AmountShown).ToList(); 
     foreach (var q in selected) 
     { 
      var listOne = new List<DiffChild>(); 
      var listTwo = new List<DiffChild>(); 
      if (q.CountAttribute != null) 
       listOne = q.DiffChild.Where(c => c.Attribute == true).OrderBy(x => rand.Next()).Take((int)q.CountAttribute).ToList(); 
      if (q.OtherCountAttribute != null) 
       listTwo = q.DiffChild.Where(d => d.Attribute != true).OrderBy(y => rand.Next()).Take((int)q.OtherCountAttribute).ToList(); 
      q.DiffChildren = listOne.Concat(listTwo).ToList(); 
     } 

EDIT: Проблема, кажется, происходит из выбранного списка и более конкретно от для цикла, где я пытаюсь выбрать конкретные объекты из полного списка, если я прохожу только это:

var selected = diffParent.DiffChild.OrderBy(x => rand.Next()).Take(diffParent.AmountShown).ToList(); 

вкладыш, кажется, работает без проблем. Кажется, я искал проблемы в неправильном месте.

+0

Возможно, вы сделали этот код для вопроса, который в порядке, но вряд ли это исключение происходит в этом точном сценарии. Может быть, в вашем реальном коде вы переназначаете существующих (великих) детей другим родителям? –

+0

Спасибо за комментарий, вы правы, код действительно предназначен для презентации. Что касается существующей части: я генерирую всех детей и внуков в качестве новых объектов, и единственный раз, когда я касаюсь существующих объектов, - это когда я повторяю список входных сущностей. –

+0

Не могли бы вы изменить свой код, чтобы он более напоминал реальный код. Интересующими частями являются то, привязаны или нет входные объекты в контексте, и если при настройке дочерних свойств заданы какие-либо ссылочные свойства. –

ответ

0

Действительно, я знал, что это будет фиксированная макс. 3 глубины, поэтому я пошел с этим дизайном, но я буду держать то, что вы сказали в будущем. По теме мне удалось исправить эту проблему, сопоставив diffParent с DTO, а затем сделав сборку и после ее сопоставления со списком объектов, которые я передал методу insert.

Смежные вопросы