Freigeben über


Code-First-Konventionen

Mit Code First können Sie ein Modell mithilfe von C# oder Visual Basic .NET-Klassen beschreiben. Die grundlegende Form des Modells wird mithilfe von Konventionen erkannt. Konventionen sind Regelsätze, die verwendet werden, um ein konzeptionelles Modell basierend auf Klassendefinitionen beim Arbeiten mit Code First automatisch zu konfigurieren. Die Konventionen werden im Namespace "System.Data.Entity.ModelConfiguration.Conventions" definiert.

Sie können Ihr Modell weiter konfigurieren, indem Sie Datenanmerkungen oder die Fluent-API verwenden. Der Vorrang wird der Konfiguration über die Fluent API gegeben, gefolgt von Datenanmerkungen und anschließenden Konventionen. Weitere Informationen finden Sie unter Data Annotations, Fluent API - Relationships, Fluent API – Types & Properties and Fluent API with VB.NET.

Eine detaillierte Liste der Code First-Konventionen ist in der API-Dokumentation verfügbar. Dieses Thema enthält eine Übersicht über die Konventionen, die von Code First verwendet werden.

Typenerkennung

Beim Verwenden der Code First-Entwicklung beginnen Sie in der Regel mit dem Schreiben von .NET Framework-Klassen, die Ihr konzeptionelles (Domänen)-Modell definieren. Zusätzlich zum Definieren der Klassen müssen Sie DbContext darüber informieren, welche Typen in das Modell einbezogen werden sollen. Dazu definieren Sie eine Kontextklasse, die von DbContext abgeleitet wird, und macht DbSet-Eigenschaften für die Typen verfügbar, die Teil des Modells sein möchten. Code First enthält diese Typen und ruft auch alle referenzierten Typen ab, auch wenn die referenzierten Typen in einer anderen Assembly definiert sind.

Wenn Ihre Typen an einer Vererbungshierarchie teilnehmen, reicht es aus, eine DbSet-Eigenschaft für die Basisklasse zu definieren, und die abgeleiteten Typen werden automatisch einbezogen, wenn sie sich in derselben Assembly wie die Basisklasse befinden.

Im folgenden Beispiel ist nur eine DbSet-Eigenschaft für die SchoolEntities-Klasse (Departments) definiert. Code First verwendet diese Eigenschaft, um alle referenzierten Typen zu ermitteln und abzurufen.

public class SchoolEntities : DbContext
{
    public DbSet<Department> Departments { get; set; }
}

public class Department
{
    // Primary key
    public int DepartmentID { get; set; }
    public string Name { get; set; }

    // Navigation property
    public virtual ICollection<Course> Courses { get; set; }
}

public class Course
{
    // Primary key
    public int CourseID { get; set; }

    public string Title { get; set; }
    public int Credits { get; set; }

    // Foreign key
    public int DepartmentID { get; set; }

    // Navigation properties
    public virtual Department Department { get; set; }
}

public partial class OnlineCourse : Course
{
    public string URL { get; set; }
}

public partial class OnsiteCourse : Course
{
    public string Location { get; set; }
    public string Days { get; set; }
    public System.DateTime Time { get; set; }
}

Wenn Sie einen Typ aus dem Modell ausschließen möchten, verwenden Sie das Attribut NotMapped oder die DbModelBuilder.Ignore fluent-API.

modelBuilder.Ignore<Department>();

Primärschlüssel-Konvention

Code First leitet ab, dass eine Eigenschaft ein Primärschlüssel ist, wenn eine Eigenschaft für eine Klasse den Namen "ID" (keine Groß-/Kleinschreibung) oder den Klassennamen gefolgt von "ID" aufweist. Wenn der Typ der Primärschlüsseleigenschaft numerisch oder GUID ist, wird sie als Identitätsspalte konfiguriert.

public class Department
{
    // Primary key
    public int DepartmentID { get; set; }

    . . .  

}

Beziehungskonvention

In Entity Framework bieten Navigationseigenschaften eine Möglichkeit zum Navigieren in einer Beziehung zwischen zwei Entitätstypen. Jedes Objekt kann eine Navigationseigenschaft für jede Beziehung aufweisen, an der es teilnimmt. Mithilfe von Navigationseigenschaften können Sie in beide Richtungen navigieren und Beziehungen verwalten, indem Sie entweder ein Referenzobjekt zurückgeben (wenn die Multiplikation entweder 1 oder Null oder 1 ist) oder eine Auflistung (wenn die Multiplikation viele ist). Code First leitet Beziehungen basierend auf den Navigationseigenschaften ab, die für Ihre Typen definiert sind.

Zusätzlich zu Navigationseigenschaften wird empfohlen, Fremdschlüsseleigenschaften für die Typen einzuschließen, die abhängige Objekte darstellen. Jede Eigenschaft mit demselben Datentyp wie die primäre Schlüsseleigenschaft des Prinzipals und mit einem Namen, der einem der folgenden Formate entspricht, stellt einen Fremdschlüssel für die Beziehung dar: '<Navigations-Eigenschaftsname><primäre Schlüsseleigenschaft des Prinzipals>', '<Prinzipal-Klassenname><primäre Schlüsseleigenschaft>', oder '<primäre Schlüsseleigenschaft des Prinzipals>'. Wenn mehrere Übereinstimmungen gefunden werden, wird Vorrang in der oben aufgeführten Reihenfolge gegeben. Bei der Erkennung von Fremdschlüsseln wird die Groß-/Kleinschreibung nicht beachtet. Wenn eine Fremdschlüsseleigenschaft erkannt wird, leitet Code First die Multiplikation der Beziehung basierend auf der Nullierbarkeit des Fremdschlüssels ab. Wenn die Eigenschaft nullwertebar ist, wird die Beziehung als optional registriert. andernfalls wird die Beziehung nach Bedarf registriert.

Wenn ein Fremdschlüssel für die abhängige Entität nicht nullfähig ist, aktiviert Code First die Löschweitergabe für die Beziehung. Wenn ein Fremdschlüssel für die abhängige Entität nullable ist, legt Code First kein kaskadierendes Löschen für die Beziehung fest, und wenn der Prinzipal gelöscht wird, wird der Fremdschlüssel auf NULL festgelegt. Das durch Konvention erkannte Mehrfach- und Kaskadierungs-Löschverhalten kann mithilfe der Fluent API überschrieben werden.

Im folgenden Beispiel werden die Navigationseigenschaften und ein Fremdschlüssel verwendet, um die Beziehung zwischen Abteilungs- und Kursklassen zu definieren.

public class Department
{
    // Primary key
    public int DepartmentID { get; set; }
    public string Name { get; set; }

    // Navigation property
    public virtual ICollection<Course> Courses { get; set; }
}

public class Course
{
    // Primary key
    public int CourseID { get; set; }

    public string Title { get; set; }
    public int Credits { get; set; }

    // Foreign key
    public int DepartmentID { get; set; }

    // Navigation properties
    public virtual Department Department { get; set; }
}

Hinweis

Wenn Sie mehrere Beziehungen zwischen denselben Typen haben (angenommen, Sie definieren die Klassen "Person " und " Book ", wobei die Person-Klasse die Navigationseigenschaften "ReviewBooks " und " AuthoredBooks " enthält und die Book-Klasse die Navigationseigenschaften "Author " und " Reviewer " enthält), müssen Sie die Beziehungen mithilfe von Datenanmerkungen oder der Fluent-API manuell konfigurieren. Weitere Informationen finden Sie unter Datenanmerkungen – Beziehungen und Fluent-API – Beziehungen.

Komplexe Typenkonvention

Wenn Code First eine Klassendefinition erkennt, bei der ein Primärschlüssel nicht abgeleitet werden kann und kein Primärschlüssel über Datenanmerkungen oder die Fluent-API registriert wird, wird der Typ automatisch als komplexer Typ registriert. Für die Erkennung komplexer Typen ist außerdem erforderlich, dass der Typ keine Eigenschaften aufweist, die auf Entitätstypen verweisen und nicht von einer Sammlungseigenschaft eines anderen Typs referenziert werden. Angesichts der folgenden Klassendefinitionen würde Code First ableiten, dass Details ein komplexer Typ ist, da er keinen Primärschlüssel aufweist.

public partial class OnsiteCourse : Course
{
    public OnsiteCourse()
    {
        Details = new Details();
    }

    public Details Details { get; set; }
}

public class Details
{
    public System.DateTime Time { get; set; }
    public string Location { get; set; }
    public string Days { get; set; }
}

Connection String-Konvention

Informationen zu den Konventionen, die DbContext zum Ermitteln der Verbindung verwendet, finden Sie unter Connections und Models.

Entfernen von Konventionen

Sie können alle im Namespace System.Data.Entity.ModelConfiguration.Conventions definierten Konventionen entfernen. Im folgenden Beispiel wird PluralizingTableNameConvention entfernt.

public class SchoolEntities : DbContext
{
     . . .

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // Configure Code First to ignore PluralizingTableName convention
        // If you keep this convention, the generated tables  
        // will have pluralized names.
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

Benutzerdefinierte Konventionen

Benutzerdefinierte Konventionen werden ab EF6 unterstützt. Weitere Informationen finden Sie unter "Erste Konventionen für benutzerdefinierten Code".