0
내가 ADO EF 코드 처음에 타이어를 발로 봤는데 다음과 같은 문제에 올라와있다

:ADO EF 코드 최초의 양방향은 다 대다 자기 참조 도전

내 모델은 아주 간단하게 가족을 나타냅니다 나무. 스칼라 속성이 FirstName 등인 Person 클래스와 부모를 나타내는 Person 컬렉션이 이고 자식을 나타내는 Person 컬렉션이 입니다.

public class Person 
{ 
    public int id { get; set; } 
    public string FirstName { get; set; } 
    public string MiddleName { get; set; } 
    public string LastName { get; set; } 
    public DateTime? DateOfBirth { get; set; } 

    List<Person> children = new List<Person>(); 
    public IList<Person> Children { get { return children; } set { children = (List<Person>)value; } } 

    List<Person> parents = new List<Person>(); 
    public IList<Person> Parents { get { return parents; } set { parents = (List<Person>)value; } } 
} 

컨텍스트 코드

public class DataContext : DbContext 
{ 
    public DbSet<Person> People { get; set; } 
} 

예상대로입니다 작성되는 데이터베이스 스키마 매우 간단합니다. PersonPersons 테이블에 대해 일대 다 2 개의 관계가있는 사람 테이블. (그런데 어쨌든 이것을 FamilyTree라는 테이블로 변경 하시겠습니까?)

그런 다음 인기있는 심슨 만화 쇼의 패밀리 트리 데이터를 사용하여 데이터베이스에 시드를 진행합니다. 나는 내가 필요한 모든 사람들을 만들고 그들을 연관시킨 다음 호머 심슨을 대표하는 사람 변수를 저장합니다.

class ProjectDBInitializer : DropCreateDatabaseIfModelChanges<DataContext> 
{ 
    protected override void Seed(DataContext context) 
    { 
     Person ph = new Person() { FirstName = "Homer", LastName = "Simpson" }; 
     Person pm = new Person() { FirstName = "Marge", LastName = "Simpson" }; 

     Person pb = new Person() { FirstName = "Bart", LastName = "Simpson" }; 
     Person pl = new Person() { FirstName = "Lisa", LastName = "Simpson" }; 

     Person phf = new Person() { FirstName = "GranPa", LastName = "Simpson" }; 
     Person phm = new Person() { FirstName = "GranMa", LastName = "Simpson" }; 

     Person pmf = new Person() { FirstName = "Marge Father", LastName = "Maiden" }; 
     Person pmm = new Person() { FirstName = "Marge Mother", LastName = "Maiden" }; 

     phf.Children.Add(ph); 
     phm.Children.Add(ph); 

     ph.Children.Add(pb); 
     ph.Children.Add(pl); 

     pb.Parents.Add(ph); 
     pb.Parents.Add(pm); 

     pl.Parents.Add(ph); 
     pl.Parents.Add(pm); 

     pm.Parents.Add(pmf); 
     pm.Parents.Add(pmm); 

     context.People.Add(ph); 
     context.SaveChanges(); 
    } 
} 

이 문제는 데이터베이스에 무엇이 들어 왔는지를 볼 때 문제가됩니다.

Marge의 모든 가족이 삽입되었지만 Homer의 부모 (GranPa 및 GranMa)는 삽입되지 않았습니다. 나는 ph varibale이 그것들에 대한 참조를 가지지 않는다는 사실과 관련이 있다고 가정합니다.

이 문제를 해결하는 가장 좋은 방법은 무엇입니까?

+0

Ladislav의 답변에 더 많은 것을 추가 할 생각이 있습니다. 답변을 읽고 동의하십시오. –

답변

2

당신이 당신의 상황에 유창 매핑을 추가해야합니다 테이블을 reneme하려면 다음 설명과 같이 인서트

public class DataContext : DbContext 
{ 
    public DbSet<Person> People { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<Person>() 
      .HasMany(p => p.Children) 
      .WithMany(c => c.Parents) 
      .Map(m => m.ToTable("FamilyTree")); 
    } 
} 

문제는 정확히이다. Homer를 삽입하려면 phf와 phm을 부모로 설정해야합니다. 또는 Homer를 추가 한 것과 같은 방법으로 People에 phm과 phf를 추가해야합니다.

자동 생성 된 POCO 개체 (EDMX에서 POCO를 생성하는 데 사용되는 T4 템플릿)는 탐색 속성에 더 복잡한 코드를 사용하며 내부적으로 관계 픽스 업을 처리하므로, 호머를 phm의 하위 컬렉션에 추가하면 호메로스에 자동으로 phm이 추가됩니다 부모님. 자신의 POCO에서 이러한 기능을 원한다면 직접 구현해야합니다. 픽스 업 방식은 데이터를로드 할 필요가없는 게으른 로딩을 유발할 수있는 단점이 있기 때문에 윈 윈 (win-win) 솔루션이 아닙니다.

+0

+1 좋은 답변 : –

+0

답장을 보내 주셔서 대단히 감사합니다. 내가 두려워했던 것처럼! 더 많은 코드를 작성해야합니다. 나는 POCO 클래스가 무엇을하고 있는지를 들여다 보았고 그것을 템플릿에 넣는 것이 합리적이다. 그것은 반복적이며 지루한 일입니다 :) 그것은 첫 번째 엔진이 관계를 올바르게 추론한다는 것을 보았을 때 proplem을 다루는 것이 아무것도 제공되지 않는다는 사실에 놀라움을 금치 못했습니다. 확실하게 관계를 수정하기 위해 일종의 그래프 트래버 설을 구현할 수 있습니다. DB. 내가 직접 한방 먹일거야. 건배. – Hugo