2012-01-08 4 views
2

Entity Framework 및 TPC 상속 With Self Referencing 하위 클래스에 문제가 있습니다.Entity Framework 코드 우선 TPC 상속 자체 참조 자식 클래스

내 클래스 정의 :

Public Class BaseObject 
    <Key()> 
    <DatabaseGenerated(DatabaseGeneratedOption.None)> 
    Public Overridable Property iId As Integer 

    <Required()> 
    Public Property iModUserId As Integer 

    <ForeignKey("iModUserId")> 
    Public Property ModUser As User 

    <Required()> 
    Public Property dtModDate As DateTime 
End Class 

Public Class User 
    Inherits BaseObject 

    <Required()> 
    Public Property sFirstName As String 

    <Required()> 
    Public Property sLastName As String 
End Class 

이 내 상황입니다

Public Class DBTestContext 
    Inherits DbContext 

    Public Property BaseObjects As DbSet(Of BaseObject) 

    Protected Overrides Sub OnModelCreating(modelBuilder As System.Data.Entity.DbModelBuilder) 
     modelBuilder.Entity(Of User)().Map(Sub(m) 
               m.MapInheritedProperties() 
               m.ToTable("tUsers") 
              End Sub) 
    End Sub 

End Class 

문제는 엔티티 프레임 워크는 "BaseClass로 생성 된 테이블에 외래 키 (FK) 관계를 설정하는 것입니다 "이고,"사용자 "클래스 용으로 생성 된 테이블이 아닙니다.

이는 아무것도 이후 주요 문제는 "BaseClass로"테이블에 삽입하도록되어 있으며, 나는 새로운 사용자 삽입 할 때, 따라서 외래 키 제약 조건 위반 : 완벽 경우

Dim context As DBTestContext = New DBTestContext() 

Dim user1 As User = New User() 

user1.iId = 1 
user1.iModUserId = 1 
user1.dtModDate = DateTime.Now 

context.Users.Add(user1) 
context.SaveChanges() 'Error occurs here. 

코드가 작동을 나는 상속 재산을 제거합니다. 이 코드는 "BaseObject"에 대한 DBSer를 제거한 다음 BaseObject 용 테이블을 만들지 않았더라도 좋지만 모든 "BaseObjects"에 대한 검색을 쉽게 수행 할 수는 없습니다.하지만 중요하지는 않습니다.

이 "솔루션"의 문제점은 "BaseObject"클래스의 표보다 많은 클래스 정의를위한 코드를 추가 할 때 (이유를 알 수 없으므로 누군가 설명 할 수 있습니까?) 외래 키 관계 다시 "BaseObject"테이블로 설정됩니다.

Public Class BaseObject 
    <Key()> 
    <DatabaseGenerated(DatabaseGeneratedOption.None)> 
    Public Overridable Property iId As Integer 

    <Required()> 
    Public Property iModUserId As Integer 

    <ForeignKey("iModUserId")> 
    Public Property ModUser As User 

    <Required()> 
    Public Property dtModDate As DateTime 

    <InverseProperty("BaseObjects")> 
    Public Overridable Property Group As ICollection(Of Group) 
End Class 

Public Class User 
    Inherits BaseObject 

    <Required()> 
    Public Property sFirstName As String 

    <Required()> 
    Public Property sLastName As String 
End Class 

<Table("tGroups")> 
Public Class Group 
    Inherits BaseObject 

    <InverseProperty("Groups")> 
    Public Overridable Property BaseObjects As ICollection(Of BaseObject) 
End Class 

외래 키 관계가 "사용자"테이블 (클래스)로 설정이 아닌 "BaseObject"테이블에되도록이 문제를 해결하는 방법이 있습니까?

나는 아래의 유창함 API를 시도했지만 결과는 동일는 :

modelBuilder.Entity(Of User)().HasRequired(Function(u) u.ModUser).WithMany().HasForeignKey(Function(u) u.iModUserId) 

답변

0

난 당신이 TPC 상속의 기본 클래스에 관계를 사용할 수 있다고 생각하지 않습니다. 그것은 이해가되지 않고 IMHO는 작동하지 않습니다. 관계는 다른 유효한 관계 = 참조 제한 조건 및 외부 키와 같이 데이터베이스에 표현되어야합니다. 데이터베이스는 기존 테이블과 관계를 어떻게 관리해야합니까? TPC는 상위 엔티티의 전체 내용이 모든 하위 엔티티의 테이블에 맵핑되어 상위 엔티티에 대한 자체 참조 관계를 모델링 할 수 없으므로 상위 엔티티에 대한 테이블이 없어야 함을의 L합니다. 파생 된 엔티티에서 다른 모든 파생 된 엔티티로 FK의 특수 세트로 연결됩니다. EF는이를 처리하는 방법을 모르기 때문에 실패합니다.

디자인을 변경하거나 TPT 상속을 사용해야합니다.

+0

전 TPC 개념을 완전히 이해하고 있으며 "BaseClass"에 대한 표를 원하지 않습니다. BaseClass의 요점은 모든 클래스에 대한 공통 기반을 가지며, 모든 클래스에 공통된 사항 중 하나는 객체를 수정 한 사람 (예 : modUser)을 저장하고 싶다는 것입니다. Entity Framework에서 BaseClass에 대한 테이블을 만들지 않도록 할 수있는 방법이 있습니까? – Thomas

+0

답변을 수락 할 수 있도록 디자인을 변경했습니다. – Thomas

관련 문제