2014-12-24 1 views
1

코드 첫 번째 접근 방식을 사용하여 Entity Framework에서 데이터 모델을 작성하는 중이지만 한 부분에서 저에게 다소 혼란 스럽습니다. 이 질문의 제목은 다소 혼란 스러울 수 있으므로 문제를 자세히 설명하겠습니다. 이 게시물의 길이는 매우 어려울 수 있지만 상당히 간단한 문제라고 생각합니다.코드 우선 접근 방식에서 많은 테이블을 하나의 테이블 관계로 정의

는 I는 다음과 같이 하나 개의 모델을 정의 : 이것은 단지 시스템의 다른 기관에 키 - 값의 속성을 저장하는 일반적인 테이블을 정의하는

public class KeyValuePair 
{ 
    [Key] 
    [MaxLength(128)] 
    [Column(Order = 0)] 
    public virtual string OwnerId { get; set; } 

    [Key] 
    [MaxLength(128)] 
    [Column(Order = 1)] 
    public virtual string Key { get; set; } 

    public virtual string Value { get; set; } 
} 

내 의도입니다. 모든 ID에 대해 GUID를 사용하고 있으므로 OwnerId은 시스템의 한 엔티티를 고유하게 참조해야하며 (OwnerId, Key) 쌍은 하나의 엔티티에서 하나의 속성을 고유하게 식별해야합니다.

즉, 내 시스템의 여러 테이블에이 KeyValuePair에 대한 1 -> 많은 관계가 있도록 허용하려고합니다. 나는에서 탐색 속성을 정의 할

OwnerId = "b4fc3e9a-2081-4989-b016-08ddd9f73db0" 
Key = "Height" 
Value = "70 in." 

을 이제 : 나는 ID b4fc3e9a-2081-4989-b016-08ddd9f73db0이있는 사람의 높이를 저장하기를 원한다면으로

그래서 예를 들어,이 테이블의 행을 저장하는 것

public class Person 
{ 
    [Key] 
    public virtual string Id { get; set; } 

    public virtual string Name { get; set; } 

    // I want this to be a navigation property 
    public ICollection<KeyValuePair> Properties { get; set; } 
} 

그러나 나는 그렇게 엔티티 프레임 워크는 인당 찾아 볼 것을 알고 PersonKeyValuePair 사이의 관계를 정의 할 방법을 잘 모르겠어요 :이 테이블에 부모 엔티티처럼 (인격 예를 데리고) on의 속성을 PersonIdKeyValuePair의 'OwnerId'에 일치시킴으로써 OwnerId은 여러 테이블에서 ID를 참조하기 때문에 KeyValuePair 모델에서 외래 키를 정의 할 수 없습니다.

그것은 내가 OnModelCreating에서 KeyValuePairPerson에서 관계를 정의하기 위해 다음과 같은 작업을 수행 할 수처럼 보이는 : OwnerId 제거,

modelBuilder.Entity<Person>() 
    .HasMany(p => p.Properties).WithMany().Map(mp => 
    { 
     mp.MapLeftKey("Id"); 
     mp.MapRightKey("OwnerId", "Key"); 
     mp.ToTable("PersonDetail"); 
    }); 

을 아니면 심지어 KeyValuePairs에게 자신의 고유 ID를 줄 수 있고, 이 작업을 수행 :

modelBuilder.Entity<Person>() 
    .HasMany(p => p.Properties).WithMany().Map(mp => 
    { 
     mp.MapLeftKey("Id"); 
     mp.MapRightKey("Id"); 
     mp.ToTable("PersonDetail"); 
    }); 

그러나 이러한 접근 방식 모두 중간 테이블의 생성이 Person를 링크 포함을 그리고 KeyValuePair 테이블, 그리고 그건 내 데이터베이스 스키마를 부풀게하고 데이터를 쿼리하는 데 더 비싼 조인을 요구 측면에서 과도한 오버 헤드처럼 보인다.

그래서 중개 테이블을 포함 할 필요가없는 관계를 정의하는 방법이 있습니까? 이 데이터베이스 디자인에 대해 잘못된 생각을하고 있습니까?

사이드 노트 : 사람이 왜 내 개체에 대한 속성을 정의하기 위해이 방법을 사용하고 궁금해하기보다는 단순히 데이터 모델에 고정 된 속성을 추가, 데이터 모델 적용 가능한 고정 속성을 사용하여 I 오전하지만, 구축하고있는 응용 프로그램에는 런타임에 사용자 정의 속성을 정의 할 수있는 기능이 필요합니다. 또한이 질문은 여러 테이블이 공유 테이블에 대해 1 -> 많은 관계가있는 다른 잠재적 시나리오에 적용 가능하다고 생각합니다.

+0

쉬운 방법 : http://stackoverflow.com/questions/13953675/modelling-polymorphic-associations-database-first-vs-code-first –

+0

마지막 코드 예제에서 구조화 된 방법 (' KeyValuePair 자체의 고유 ID)는 일대 다 (즉, 'HasMany' + WithMany')가 아닌 다 대다 (Many-to-Many)로 구성됩니다. – IronMan84

답변

0

내가 할 수있는 유일한 방법은 (그리고 나는 이것이 최고의 아이디어가 아니라는 것을 인정할 것이다. 그러나 당신이 묻는대로 할 것이다.)이 관계를 가질 필요가있는 어떤 클래스라도 가질 수있을 것이다. KeyValuePair은 완전히 구현 된 탐색 속성과 ID 필드를 포함하는 추상 클래스를 구현합니다. "완전히 구현 됨"이라 함은 실제로 매핑 된 관계를 의미하지는 않습니다. 그게 테이블에 나가서 실제로 주어진 ID와 관련된 속성을 잡으려면 DbContext을 사용해야한다는 뜻입니다. 이 같은

뭔가 :

public abstract class HasKeyValuePairs 
{ 
    [Key] 
    public virtual string Id { get; set; } 

    [NotMapped] 
    public ICollection<KeyValuePair> Properties 
    { 
     get 
     { 
      using(var db = new DbContext()) 
      { 
      return db.KeyValuePairs.Where(kvp => kvp.OwnerID == this.ID); 
      } 
     } 
    } 
} 

EF 때문에,이 같은 그 일에 많은 추가 오버 헤드가 안된다, (당신이 virtual 키워드를 사용하고 있는지 주어진) 게으른로드를 사용하는 가정 어쨌든 당신이 그들을 부르면 속성을 선택하기 위해 데이터베이스로 돌아 가야 할 것입니다. 나중에 코드에서 ContextDisposedException이 발생하지 않도록하려면 List을 반환해야하지만 적어도 실행 및 실행시킬 수 있습니다.

관련 문제