2

저는 EF 4.1 Code First를 사용하고 있으며 다음과 같은 모델을 만들려고합니다.EF 4.1 : 복합 키와 공유 컬럼과의 다 대다 관계 매핑?

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

public class Banana 
{ 
    public int AppleId {get;set;} 
    public int Id {get;set;} 
    public virtual ICollection<Coconut> Coconuts {get;set;} 
} 

public class Coconuts 
{ 
    public int AppleId {get;set;} 
    public int Id {get;set;} 
    public virtual ICollection<Banana> Bananas {get;set;} 
} 

데이터베이스는 다음과 같습니다. Fruit

이것은 EF 협약을 따르지 않는 기존 스키마이므로 Fluent API를 사용하여 엔티티를 데이터베이스에 매핑합니다. 매핑은 다음과 같습니다. 나는 그런 식으로두면

public class BananaMapping : EntityTypeConfiguration<Banana> 
{ 
    public BananaMapping() 
    { 
     HasKey(e => new { e.AppleId, e.Id }) 
      .ToTable("Bananas", "fruit"); 
     Property(e => e.Id) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

     HasMany(e => e.Coconuts) 
      .WithMany(s => s.Bananas) 
      .Map(l => 
        { 
         l.ToTable("BananaCoconuts", "fruit"); 
         l.MapLeftKey("AppleId", "BananaId"); 
         l.MapRightKey("AppleId", "CoconutId"); 
        }); 
    } 

(애플과 코코넛이 너무 매핑하지만,지면 관계 상 자세한 내용은 생략) , 그것은 때문에 공유 컬럼의 MetadataException를 생성합니다. "Schema specified is not valid. Errors: (110,6) : error 0019: Each property name in a type must be unique. Property name 'AppleId' was already defined."

이지나 얻으려면, 단순히 AppleId의 다른 이름 사본을 노출 BananaCoconuts에 계산 된 열을 생성하고 BananaAppleId을했다. 다소 냄새 나는 확실히 hacktastic, 그것은 MetadataException 과거 저를 얻었다 동안 내가로부터 새로운 링크를 추가하려고 할 때까지 나는

HasMany(e => e.Coconuts) 
    .WithMany(s => s.Bananas) 
    .Map(l => 
     { 
      l.ToTable("BananaCoconuts", "fruit"); 
      l.MapLeftKey("BananaAppleId", "BananaId"); 
      l.MapRightKey("AppleId", "CoconutId"); 
     } 
    ); 

... 혼자 (분명히)이 FKS를 떠나 같이하는 매핑을 변경 암호. 변경 사항 저장

var banana = dataContext.FindBanana(appleId, bananaId); 
var coconut = dataContext.FindCoconut(appleId, coconutId); 
banana.Coconuts.Add(coconut); 
dataContext.SaveChanges(); 

는 DbUpdateException

An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details. 

그리고 내부 (몇 가지 예외 아래로, 실제로) ...

{"The column \"BananaAppleId\" cannot be modified because it is either a computed column or is the result of a UNION operator."} 

을 던졌습니다 그리고 지금은 아이디어에서입니다. :) 데이터베이스 스키마는 우리가 필요로하는 것을 정확하게 모델링합니다 (계산 된 열 제외). 이것을 처리하는 가장 좋은 방법은 무엇입니까? 나는 BananaAppleId을 "실제"열로 만들고, 외래 키를 변경하고, 동기화해서는 안되지만 중복해서 저장된 데이터를 저장하는 것에 미치지 않습니다.

답변

3

조인 테이블에는 기본 키로 4 개의 컬럼이 있어야하고 각각은 기본 테이블에 대한 외부 키입니다. EF는 4 개의 열 값 모두를 전송하여 레코드를 삽입하므로 계산 된 열을 설정할 수 없습니다. 그래서 귀하의 경우

HasMany(e => e.Coconuts) 
    .WithMany(s => s.Bananas) 
    .Map(l => 
     { 
      l.ToTable("BananaCoconuts", "fruit"); 
      l.MapLeftKey("BananaAppleId", "BananaId"); 
      l.MapRightKey("CoconutAppleId", "CoconutId"); 
     } 
    ); 

그렇지 않으면 별도의 엔티티로 조인 테이블을 매핑해야합니다.

+0

감사합니다. 이것이 우리가 한 일이며, BananaAppleId와 CoconutAppleId 사이에 체크 제약 조건을 두어 동기화 상태를 유지해야합니다. – Josh