2015-01-12 2 views
0

는 최근에 나는엔티티 프레임 워크 - 할당 문제를 나열

parent.Children = new List<ChildObject> { new ChildObject("newChild", "newValue") }; 

실제로 어린이의 목록에 새 자식을 추가 왜 프로그램 이 사람이 나에게 설명 할 수있는 다음과 같은 대신 오래된 제거 주어진 EntityFramework 6 이상한 행동을 spoted 자녀를 추가하고 새 자녀를 추가하십시오. 부모를로드 할 db.Parents.Include(x => x.Children).First()를 사용

이 의식 디자인 선택이었다 ...이 동작조차 낯선하게 문제를 해결하거나 실제로 버그?

전체 테스트 프로그램 :

당신이 당신의 DbContext에 SaveChanges를 호출
using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations.Schema; 
using System.Data.Entity; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace EF_PlayWithList 
{ 
    public class ChildObject 
    { 
     public int Id { get; protected set; } 

     public int ParentId { get; protected set; } 
     public string Name { get; protected set; } 
     public string Value { get; protected set; } 

     protected ChildObject() { } 

     public ChildObject(string name, string value) 
     { 
      this.Name = name ?? ""; 
      this.Value = value ?? ""; 
     } 

     public override string ToString() 
     { 
      return string.Format("{0}: {1}", this.Name, this.Value); 
     } 
    } 

    public class ParentObject 
    { 
     public int Id { get; protected set; } 
     public string Name { get; protected set; } 

     public virtual IList<ChildObject> Children { get; set; } 

     protected ParentObject() { } 

     public ParentObject(string name) 
     { 
      this.Name = name; 
      this.Children = new List<ChildObject>(); 
     } 

     public void AddChild(ChildObject child) 
     { 
      this.Children.Add(child); 
     } 

     public override string ToString() 
     { 
      return string.Format("Parent '{0}' with {1} childs.", this.Name, this.Children.Count); 
     } 
    } 

    class TestDbContext : DbContext 
    { 
     public DbSet<ParentObject> Parents { get; set; } 

     public TestDbContext() 
      : base() 
     { 

     } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      modelBuilder.Entity<ParentObject>() 
       .HasMany(x => x.Children) 
       .WithRequired() 
       .HasForeignKey(x => x.ParentId) 
       .WillCascadeOnDelete(); 

      modelBuilder.Entity<ParentObject>() 
       .HasKey(x => x.Id); 

      modelBuilder.Entity<ParentObject>() 
       .Property(x => x.Id) 
       .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

      modelBuilder.Entity<ChildObject>() 
       .HasKey(x => new { x.Id, x.ParentId }); 

      modelBuilder.Entity<ChildObject>() 
       .Property(x => x.Id) 
       .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      Database.SetInitializer(new DropCreateDatabaseAlways<TestDbContext>()); 

       using (var db = new TestDbContext()) 
       { 
        var parent = new ParentObject("superFooParent"); 
        parent.AddChild(new ChildObject("foo", "1")); 
        parent.AddChild(new ChildObject("bar", "2")); 

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

       using (var db = new TestDbContext()) 
       { 
        var parent = db.Parents.First(); 

        parent.Children = new List<ChildObject> 
        { 
         new ChildObject("newChild", "newValue") 
        }; 

        db.SaveChanges(); 
       } 

       using (var db = new TestDbContext()) 
       { 
        foreach (var parent in db.Parents.Include(x => x.Children)) 
        { 
         Console.WriteLine(parent); 

         foreach (var child in parent.Children) 
         { 
          Console.WriteLine("\t{0}", child); 
         } 
        } 
       } 

      Console.ReadLine(); 
     } 
    } 
} 
+0

EF 디자인 팀에게 이것이 의도적인지 물어보아야 만합니다. 그렇다면 왜 그 결정을 내렸습니까? 우리는 단지 추측 할 수 있습니다. – Servy

+0

위와 같이 추측 할 수는 있지만, 모든 어린이를 명시 적으로 제거해야한다는 것은 나쁘지 않다고 생각합니다. 또한 이러한 종류의 대체를 허용하면 모든 종류의 참조 무결성 문제를 열어 볼 수 있습니다. – barrick

+0

이전 버전과 비교해 차이점을 발견하는 것이 좋습니다. 아니면 EF가 왜 이렇게 행동하는지 묻는 것입니까? –

답변

1

, 프레임 워크는 경우 ... 등 제거 추가가 수정되었습니다 무엇을 볼 수에 대한를 알고있는 모든 엔티티 을 검사 이전의 자식 목록은로드되지 않았으므로 DbContext는 해당 항목을 알지 못하고 제거되지 않습니다. 그것이 의도 한 행동입니다. 프레임 워크에서 데이터베이스를 변경하려면 DbContext가 영향을받는 엔티티를로드하도록 허용해야합니다. 그렇지 않으면 순수 SQL을 사용해야합니다.