Entity Framework Code First TPC Inheritance Self-Referencing Child Class

做~自己de王妃 提交于 2019-12-10 23:49:11

问题


I have a problem With Entity Framework and TPC Inheritance With Self-Referencing Child Class.

My Class definitions:

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

This is my Context

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

The problem is that Entity Framework sets the Foreign Key (FK) relationship to the table that is created for the "BaseClass", and NOT to the table created for the "User" class.

This is a major problem since nothing is supposed to be inserted to the "BaseClass" table, and therefore the foreign key constraint is violated when I insert a new user:

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.

The code works perfectly if I remove the inheritance. The code also work if I remove the DBSer for "BaseObject" and then no table is created for BaseObject, wich is good, but then I cannot easily do a search for all "BaseObjects", wich is bad (but not essential).

The problem with this "solution" is that when I add the code below for more class definitions than the a table for the "BaseObject" class reappears (do not know why, can somebody explain?) and the foreign key relationship is once again set to the "BaseObject" table.

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

Is there any way to fix this so that the foreign key relationship is set to the "User" table (Class), and not to the "BaseObject" table?

I have tried with the below Fluent API, but the result is the same:

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

回答1:


I don't think you can use relation to base class of TPC inheritance. It doesn't make sense and IMHO it cannot work. The relationship must be expressed in database as any other valid relationship = referential constraint and foreign key. How should database manage relation with non existing table? TPC means that there should not be any table for parent entity because whole content of the parent entity is mapped to the table for every child entity so self referencing relation to parent entity cannot be modeled. It would lead to special set of FKs from derived entity to all other derived entities. Because EF doesn't know how to handle it, it fails.

I expect you must either change your design or use TPT inheritance.



来源:https://stackoverflow.com/questions/8781707/entity-framework-code-first-tpc-inheritance-self-referencing-child-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!