实体框架代码第一个TPC继承自引用子类

时间:2012-01-08 21:55:36

标签: entity-framework-4.1 ef-code-first

我的实体框架和使用自引用子类的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

问题是Entity Framework将外键(FK)关系设置为为“BaseClass”创建的表,而不是为“User”类创建的表。

这是一个主要问题,因为不应该将任何内容插入“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.

如果删除继承,代码将完美运行。如果我删除DBSer for“BaseObject”然后没有为BaseObject创建表,这个代码也可以工作,这很好,但是我不能轻易地搜索所有“BaseObjects”,这很糟糕(但不是必需的)。< / p>

这个“解决方案”的问题在于,当我添加下面的代码以获得更多的类定义而不是“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

有没有办法解决这个问题,以便将外键关系设置为“User”表(Class),而不是“BaseObject”表?

我尝试使用下面的Fluent API,但结果是一样的:

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

1 个答案:

答案 0 :(得分:0)

我认为你不能将关系用于TPC继承的基类。它没有意义,恕我直言,它无法正常工作。该关系必须在数据库中表示为任何其他有效关系=引用约束和外键。数据库应如何管理与非现有表的关系? TPC意味着父实体不应该有任何表,因为父实体的整个内容被映射到每个子实体的表,因此无法对父实体的自引用关系建模。它将导致从派生实体到所有其他派生实体的特殊FK集。因为EF不知道如何处理它,它失败了。

我希望您必须更改设计或使用TPT继承。