2012-07-09 3 views
3

먼저 Entity Framework 4.3 코드를 사용하고 있습니다. A 클래스의 두 속성과 B 클래스의 컬렉션 사이에 두 개의 "일대 다"관계를 만드는 방법은 무엇입니까? 내 모델 동일한 컬렉션에 두 개의 속성을 일대일로 매핑

:

public class Shaft 
{ 
    public int Id { get; set; } 

    public virtual Coupling FirstEnd { get; set; } 
    public virtual Coupling SecondEnd { get; set; } 
} 

public class Coupling 
{ 
    public int Id { get; set; } 

    public virtual ICollection<Shaft> Shafts { get; set; } 
} 

답변

2

음이, 일대 다 관계가 호출 하나 - 투 - 많은 관계의 일단과 많은 요소 요소가 있기 때문에 다른 끝. 0 또는 1 - 대다수 관계를 가질 수 있습니다. 이는 많은 수가없는 쪽의 요소가 null (또는 NULL 데이터베이스) 일 수 있음을 의미합니다.

는 당신이 정의하려고하는 것은 - 투 - 많은 (혹은 0 또는 1 또는 두 개의 - 투 - 많은) 관계이다. 그러한 것은 관계형 데이터베이스에도 없으며 Entity Framework에도 존재하지 않습니다.

EF와 관계를 정의 할 때 원본 및 대상 클래스에 항상 쌍의 쌍의 탐색 속성이 필요합니다. 이며 내비게이션 속성의 하나의을 생략 할 수는 있지만이 관계의 끝을 이미 다른 관계에 속한 다른 탐색 속성으로 이동할 수있는 것은 아닙니다.

두 개의 탐색 속성 FirstEndSecondEndShaft에 있기 때문에 특정 두 개의 외래 키를 나타낼 수 있습니다. 따라서 Coupling에 두 개의 콜렉션이 필요하거나 기존 속성 Coupling.ShaftsFirstEnd 또는 SecondEnd 중 하나와 관련시킬 수 있지만 둘 다 가질 수는 없습니다. 다른 참고 문헌은 Coupling에있는 "보이지 않는"탐색되지 않은 탐색 모음을 나타냅니다. EF는 첫 번째를 덮어 쓰는 두 번째 매핑 블록을 사용하여 SecondEndShafts 사이의 관계를 만든 다음 FirstEnd과 노출되지 않은 관계 끝인 Coupling, 사이의 관계를 만듭니다. 하지Shafts 다시)

이 명 컬렉션을 가진 솔루션 - 제 생각에 더 의미가 있습니다 -이과 같습니다.

public class Coupling 
{ 
    public int Id { get; set; } 

    public virtual ICollection<Shaft> ShaftsWithFirstEndHere { get; set; } 
    public virtual ICollection<Shaft> ShaftsWithSecondEndHere { get; set; } 
} 

그리고이 매핑 :

modelBuilder.Entity<Coupling>() 
    .HasMany(x => x.ShaftsWithFirstEndHere) 
    .WithOptional(x => x.FirstEnd); 

modelBuilder.Entity<Coupling>() 
    .HasMany(x => x.ShaftsWithSecondEndHere) 
    .WithOptional(x => x.SecondEnd); 

당신은 하나 개의 컬렉션에 togother 두 개의 컬렉션을 연결하는 읽기 전용이 아닌 매핑 ​​도우미 속성을 만들 수 있지만 두 탐색 컬렉션이 이미로드 된 후이 연결은 메모리에 일어날 것입니다 :이

public class Coupling 
{ 
    public int Id { get; set; } 

    public virtual ICollection<Shaft> ShaftsWithFirstEndHere { get; set; } 
    public virtual ICollection<Shaft> ShaftsWithSecondEndHere { get; set; } 

    // not mapped to DB because it has only a getter = readonly 
    public IEnumerable<Shaft> Shafts 
    { 
     get { return ShaftsWithFirstEndHere.Concat(ShaftsWithSecondEndHere); } 
    } 
} 

그러한 연결을 자동으로 수행하는 매핑이 아닙니다. 일대 다 관계의 탐색 컬렉션 속성은 종속 테이블 (예 : Shaft)의 외래 키에 의한 쿼리 결과 일뿐입니다.컬렉션을 채우는 데 사용되는 외래 키 (예를 들어 Include을 사용하거나 지연로드가 트리거 될 때)는 관계 매핑에 의해 잘 정의되며 하나의 키 - FirstEnd의 키 또는 SecondEnd의 키 중 하나만 사용할 수 있지만 둘 다 사용할 수는 없습니다. . 달성하고자하는 것은 두 개의 서로 다른 외래 키에 의한 두 개의 쿼리의 결합 된 연결 결과입니다. 그리고 그것은 관계 매핑으로는 불가능합니다.

+0

저는 아직도 세계에서 신선합니다. 보여? 이 점을 명확히 해 주셔서 감사합니다. 내 솔루션은 데이터베이스에서 예상되는 동작을 제공하지만 일단 EF를 사용하려고하면 큰 오류가 발생합니다. 우연히 우연히 다른 초보자를 잘못 유도하는 것을 원하지 않기 때문에 삭제하겠습니다. –

관련 문제