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 Gruppen von Regeln, die verwendet werden, um bei der Arbeit mit Code First ein konzeptionelles Modell automatisch basierend auf Klassendefinitionen 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. Vorrang wird der Konfiguration über die Fluent-API gegeben, gefolgt von Datenanmerkungen und Konventionen. Weitere Informationen finden Sie unter Datenanmerkungen, Fluent-API – Beziehungen, Fluent-API – Typen & Eigenschaften and Fluent-API mit VB.NET.

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

Typ-Discovery

Bei der Code-First-Entwicklung beginnen Sie in der Regel mit dem Schreiben von .NET Framework-Klassen, die Ihr konzeptionelles Modell (Domänenmodell) definieren. Zusätzlich zum Definieren der Klassen müssen Sie DbContext darüber informieren, welche Typen Sie in das Modell einbeziehen wollen. Dazu definieren Sie eine Kontextklasse, die von DbContext abgeleitet wird und DbSet-Eigenschaften für die Typen verfügbar macht, die Sie als Teil des Modells haben wollen. Code First wird diese Typen enthalten und auch alle referenzierten Typen pullen, selbst 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 zu pullen.

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 NotMapped-Attribut oder die DbModelBuilder.Ignore-Fluent-API.

modelBuilder.Ignore<Department>();

Primärschlüsselkonvention

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

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

    . . .  

}

Beziehungskonvention

Im Entity Framework bieten Navigationseigenschaften eine Möglichkeit, in einer Beziehung zwischen zwei Entitätstypen zu navigieren. Jedes Objekt kann für jede Beziehung, an der es beteiligt ist, über eine Navigationseigenschaft verfügen. Mit Navigationseigenschaften können Sie Beziehungen in beide Richtungen navigieren und verwalten, wobei entweder ein Verweisobjekt zurückgegeben wird (wenn die Multiplizität eins oder null-oder-eins ist), oder eine Auflistung (wenn die Multiplizität viele ist). Code First leitet Beziehungen basierend auf den Navigationseigenschaften ab, die für Ihre Typen definiert sind.

Zusätzlich zu Navigationseigenschaften empfehlen wir, dass Sie Fremdschlüsseleigenschaften für die Typen einschließen, die abhängige Objekte darstellen. Jede Eigenschaft mit demselben Datentyp wie die Primärschlüsseleigenschaft des Prinzipals und mit einem Namen, der einem der folgenden Formate folgt, stellt einen Fremdschlüssel für die Beziehung dar: „<Name der Navigationseigenschaft><Eigenschaftsname des Primärschlüssels des Prinzipals>“, „<Klassenname des Prinzipals><Eigenschaftsname des Primärschlüssels>“ oder „<Eigenschaftsname des Primärschlüssels des Prinzipals>“. Wenn mehrere Übereinstimmungen gefunden werden, gilt die oben angegebene Rangfolge. Bei der Erkennung von Fremdschlüsseln wird die Groß-/Kleinschreibung nicht beachtet. Wenn eine Fremdschlüsseleigenschaft erkannt wird, leitet Code First die Multiplizität der Beziehung basierend auf der NULL-Zulässigkeit des Fremdschlüssels ab. Wenn die Eigenschaft Nullwerte zulässt, wird die Beziehung als optional registriert, andernfalls wird die Beziehung bei Bedarf registriert.

Wenn ein Fremdschlüssel für die abhängige Entität keine Nullwerte zulässt, legt Code First die Kaskadenlöschung für die Beziehung fest. Wenn ein Fremdschlüssel für die abhängige Entität Nullwerte zulässt, legt Code First keine Kaskadenlöschung für die Beziehung fest, und wenn der Prinzipal gelöscht wird, wird der Fremdschlüssel auf NULL festgelegt. Das von der Konvention erkannte Verhalten für Multiplizität und Kaskadenlöschung kann mithilfe der Fluent-API überschrieben werden.

Im folgenden Beispiel werden die Navigationseigenschaften und ein Fremdschlüssel verwendet, um die Beziehung zwischen den Klassen „Department“ und „Course“ 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 Klasse Person die Navigationseigenschaften ReviewedBooks und AuthoredBooks enthält und die Klasse Book 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 ist, 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 dass er 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; }
}

Verbindungszeichenfolgekonvention

Informationen zu den Konventionen, die DbContext zum Entdecken der Verbindung verwendet, finden Sie unter Verbindungen und Modelle.

Entfernen von Konventionen

Sie können alle im Namespace System.Data.Entity.ModelConfiguration.Conventions definierten Konventionen entfernen. Das folgende Beispiel entfernt PluralizingTableNameConvention.

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 Benutzerdefinierte Code First-Konventionen.