У меня проблема с 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
Проблема заключается в том, что 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 для «BaseObject», а затем не создается таблица для 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"?
Я пробовал использовать приведенный ниже Fluent API, но результат тот же:
modelBuilder.Entity(Of User)().HasRequired(Function(u) u.ModUser).WithMany().HasForeignKey(Function(u) u.iModUserId)