2016-09-13 2 views
2

Entity Framework 6 Code First를 사용하여 TPH 상속을 구현하려고하고 상속 된 형식의 관계에 문제가 있습니다.Entity Framework 상속 및 관계

내 코드

public abstract class Base... 

public class Inherited1 : Base 
{ 
public virtual Type1 Rel { get; set; } 
... 

public class Inherited2 : Base 
{ 
public virtual Type1 Rel {get;set;} 
... 

그래서 상속 유형이 "동일한"관계를 가지고있다. 상속 자체가 잘 작동하지만 내가 가진 문제는 Type1 테이블과의 관계가 두 번 (논리 ...) 추가되고 다른 관계는 Inherited2.Id에서 Type1.Id로 Inherited2.Type1Id 대신 Type1.Id 첫 번째 관계가 (올바르게)인지 확인하십시오.

변경된 형식 이름이있는 부분 코드 샘플을 설명하는 것이 적절하지 않은지 잘 모르겠지만 그 점을 알고 싶습니다. 필요한 경우 자세한 내용을 문의하십시오.

아마

UPDATE 내가 문제를 설명하는 샘플 Github에서의 REPO를 만들었습니다
제대로이를 구현할 수 있습니다. 제가 잘못하고있는 것을 말해주십시오. https://github.com/antsim/EntityFrameworkTester

+0

무엇을 사용하고 있습니까? 유창한 API 또는 특수 효과? 두 경우 모두 사용중인 코드를 보여줍니다. – Monah

+0

이러한 관계와 관련된 유일한 유창한 API는 입니다. modelBuilder.Entity ( ) .HasMany (x => x.Inherited1) .WithRequired (x => x. Type1) .WillCascadeOnDelete(); –

+0

아래의 내 대답에 TPT와 TPH 모두 참조로 추가했습니다. – Monah

답변

2

봅니다 사용하는 당신이 TPT이

modelBuilder.Entity<Inherited1>() 
      .ToTable("Inherited1s") 
      .HasKey(x => x.YourKey) 
      .HasRequired(x=>Type1) 
      .WithMany() 
      .HasForeignKey(x=>Type1Id) 
      .WillCascadeOnDelete(false); 

modelBuilder.Entity<Inherited2>() 
      .ToTable("Inherited2s") 
      .HasKey(x => x.YourKey) 
      .HasRequired(x=>Type1) 
      .WithMany() 
      .HasForeignKey(x=>Type1Id) 
      .WillCascadeOnDelete(false); 

이 원하는 경우

1 다음 - 더 자세한 내용은 TPH

modelBuilder.Entity<Base>() 
      .ToTable("YourTableName") 
      .HasRequired(m=>m.Type1) 
      .WithMany() 
      .HasForeignKey(m=>m.Type1Id) 
      .WillCascadeOnDelete(); // true or false as you want 

을 원하는 경우이 article

을 확인할 수 있습니다

제공된 샘플을 기반으로

  • AttachmentDocument이 파일에서 상속됩니다 당신은 하나 개의 테이블이 Discriminator 필드로 생성된다는 것을 의미합니다 TPH을 사용하고 있습니다.
  • DocumentFileContainer은 외부 키가 FileContainerId 따라서
  • FileContainerAttachmentFile 표의 Document에 생성되어야 수단 형 0..N의 관계가 타입 0..1의 관계를 가지고 다음 다른 널 (NULL) 외래 키는 사용자가 제공 한 예에서 테이블 파일

에 생성됩니다, 나는 다음과 같이 변경

  1. 추가 FileContainerId했다 테이블 문서에
  2. 테이블 첨부 파일에 TestContext에 만든
  3. 변경을 FileContainerAttachmentId을 추가하는 파일 테이블이 두 관계 일뿐만 아니라 판별 필드가 (출력이 정확했다

     modelBuilder.Entity<FileContainer>() 
          .HasOptional(x => x.Document) 
          .WithMany() 
          .HasForeignKey(t => t.DocumentId) 
          .WillCascadeOnDelete(false); 
    
         modelBuilder.Entity<Document>() 
          .HasRequired(t => t.FileContainer) 
          .WithMany() 
          .HasForeignKey(t => t.FileContainerId) 
          .WillCascadeOnDelete(false); 
    
         modelBuilder.Entity<Attachment>() 
          .HasRequired(t => t.FileContainer) 
          .WithMany() 
          .HasForeignKey(t => t.FileContainerAttachmentId) 
          .WillCascadeOnDelete(false); 
    

했다 컨테이너가있는 문서의 경우 및 컨테이너가있는 문서의 경우).

내 의견에 더 나은 솔루션은 다음과 같습니다

  1. Attachment, Document와 클래스 FileType (Id, Name)를 추가하고, 단 하나의 관계 0..N를 추가하려면 File
  2. 에서 외래 키로 추가하기
  3. FileContainer 사이와 File 확인하려면 같은 컨테이너 유형 문서의 파일에서 하나의 레코드 만

희망이 당신을 도울 수

+0

TPH 예제에 .WithMany가 있습니다. 나는 그런 식으로 작동하게 만들었지 만 Type1에 ​​0..1이 있다면 어떻게 될까? –

+0

0..1은 n = 1 인 경우 0..n의 특수한 경우이므로 동일한 논리를 적용 할 수 있지만 HasRequired 대신 HasOptional을 사용해야합니다. – Monah

+0

이러한 문제를 재현하고 테스트하기 위해 github repo를 만들었습니다. 시간이 있으면 도움을 줄 수 있습니다. 필자는 readme.md에서 원하는 결과와 현안을 설명하려고 노력했습니다. https://github.com/antsim/EntityFrameworkTester –

관련 문제