Entity Framework Tabelle pro Hierarchie
Was ist der Vererbungstyp in Entity Framework?
Entity Framework-Code erstellt zunächst Tabellen für jede konkrete Domänenklasse. Sie können Ihre Domänenklassen auch mithilfe der Vererbung entwerfen.
- In der objektorientierten Programmierung können wir "hat eine" und "ist eine" Beziehung einschließen, wohingegen in einem SQL-basierten relationalen Modell nur eine "hat eine" Beziehung zwischen Tabellen vorhanden ist und die Typvererbung nicht unterstützt wird.
- Wie würden Sie also objektorientierte Domänenklassen mit der relationalen Datenbank abbilden?
Antworten
Es gibt drei Ansätze, um eine Vererbungshierarchie in Entity Framework darzustellen.
Tabelle pro Hierarchie (TPH)
Die TPH-Vererbung verwendet eine Datenbanktabelle, um Daten für alle Entitätstypen in einer Vererbungshierarchie zu verwalten.
- Eine gesamte Klassenhierarchie kann einer einzelnen Tabelle zugeordnet werden.
- Die Tabelle enthält Spalten für alle Eigenschaften aller Klassen in der Hierarchie.
- Die konkrete Unterklasse, die durch eine bestimmte Zeile dargestellt wird, wird durch den Wert einer Typunterscheidungsspalte identifiziert.
TPH in Code First
Sie müssen in Code First nichts Besonderes tun, um TPH zu aktivieren. Dies ist die Standardstrategie für die Vererbungszuordnung. Hier ist das sehr einfache Modell, das eine abstrakte Klasse Person
und zwei nicht abstrakte Klassen Student
und Teacher
. Student
und Teacher
erben die Personenklasse.
public abstract class Person
{
public int Id { get; set; }
public string FullName { get; set; }
}
public class Student : Person
{
public DateTime EnrollmentDate { get; set; }
}
public class Teacher : Person
{
public DateTime HireDate { get; set; }
}
public class EntityContext : DbContext
{
public DbSet<Person> People { get; set; }
}
Fügen wir der Datenbank einige neue Datensätze hinzu.
using (var context = new EntityContext())
{
Student student = new Student()
{
FullName = "Mark",
EnrollmentDate = DateTime.Now
};
Teacher teacher = new Teacher()
{
FullName = "John",
HireDate = DateTime.Now
};
context.People.Add(student);
context.People.Add(teacher);
context.SaveChanges();
}
Wie Sie im DB-Schema sehen können, hat Code First alle Eigenschaften in einer Tabelle hinzugefügt und außerdem eine Diskriminatorspalte hinzugefügt, um zwischen persistenten Klassen zu unterscheiden.

TPH hat ein Hauptproblem: Spalten für Eigenschaften, die von Unterklassen deklariert werden, sind in der Datenbank nullfähig.
- Beispielsweise erstellte Code First eine Spalte (DATETIME, NULL), um die HireDate-Eigenschaft in der Teacher-Klasse und EnrollmentDate in der Student-Klasse zuzuordnen.
- Die Lehrerinstanz verfügt nicht über eine EnrollmentDate-Eigenschaft. Das Feld EnrollmentDate muss für diese Zeile NULL sein.
- Ebenso hat die Studenteninstanz keine HiretDate-Eigenschaft, daher muss das HiretDate-Feld für diese Zeile NULL sein.
Generierte SQL anzeigen
Untersuchen wir die SQL-Abfrage, die eine Liste aller Schüler und Lehrer zurückgibt.
var query = context.People.ToString();
Diese Abfrage hat die folgenden SQL-Anweisungen generiert, die in der Datenbank ausgeführt wurden.
SELECT
[Extent1].[Discriminator] AS [Discriminator],
[Extent1].[Id] AS [Id],
[Extent1].[FullName] AS [FullName],
[Extent1].[EnrollmentDate] AS [EnrollmentDate],
[Extent1].[HireDate] AS [HireDate]
FROM [dbo].[People] AS [Extent1]
WHERE [Extent1].[Discriminator] IN (N'Student',N'Teacher')
Weitere Informationen finden Sie unter Vererbung mit EF-Code zuerst: Teil 1 - Tabelle pro Hierarchie (TPH).