2014-01-20 1 views
8

Hier sind meine Modelle. Ich habe Eins-zu-eins-Zuordnung für Fahrzeug und Fahrer. Ich werde das Fahrzeug zuerst erstellen lassen und dann den Fahrer dem Fahrzeug zuordnen.EF Foreign Key mit Fluent API

public class Driver 
{ 
    public int Id { get; set; } 
    public String Name { get; set; } 
    public int VehicleId { get; set; } 
    public virtual Vehicle Vehicle { get; set; } 
} 

public class Vehicle 
{ 
    public int Id { get; set; } 
    public String Name { get; set; } 

    public virtual Driver Driver { get; set; } 

    public int VehicleGroupId { get; set; } 
    public virtual VehicleGroup Vehicles { get; set; } 
} 

Ich möchte die VehicleId-Eigenschaft in der Driver-Klasse verwenden, um die ID des Fahrzeugs zu behalten, das der Fahrer fährt.

Ich habe die folgende Fluent API-Code geschrieben:

modelBuilder.Entity<Vehicle>() 
      .HasRequired(d => d.Driver) 
      .WithRequiredPrincipal(); 

Aber es schafft eine neue Spalte in Treiber Tabelle - Vehicle_VehicleId und ordnet sie dem VehicleID auf Fahrzeug Tisch. Ich möchte die VehicleId der Driver-Tabelle zuordnen.

Außerdem bin ich brandneue EF und Fluent API. Ich finde es sehr verwirrend, zwischen WithRequiredDependent und WithRequiredPrincipal zu wählen. Wäre froh, wenn Sie es in einfachen Worten beschreiben können. Vielen Dank.

+2

Sie der Abhängigen und Prinzipien wie Entity Framework denken können Sie fragen: ‚Wenn Sie wollen, um Datensätze dieser Tabellen einzufügen, wo sollte ich zuerst Datensätze, Tabelle A oder Tabelle B einfügen? Wenn Sie Tabelle A als Prinzipal auswählen, enthält Tabelle B einen Fremdschlüssel für Tabelle A. Die Fluent-API hat übrigens eine ausgezeichnete C# -Dokumentation, Sie sollten die Beschreibung von "WithRequiredDependent" und "WithRequiredPrincipal" sorgfältig lesen. – Moeri

Antwort

18

Diese Zeile:

public int VehicleID {get; einstellen; }

sagt EF, through code-conventions, dass Sie ein Fremdschlüssel zu Vehicle zeigt in Driver wollen.

sagte Dieser aufschluss EF, dass Sie eine 1 wollen: 1-Beziehung Driver-Vehicle:

öffentliches virtuelles Fahrzeug Fahrzeug {get; einstellen; }

Sie sollten beide entfernen und bleiben Sie mit Ihrer Fluent-API-Konfiguration.

Betreffend WithRequiredPrincipal vs.WithRequiredDependent:

Sie sind eine obligatorische Beziehung zwischen Vehicle und Driver, mit Navigation Vehicle-Driver Angabe, also: Das Fahrzeug 1 -> 1 Driver

(Fahrzeug ist das wichtigste und Driver die abhängig, da die Navigationseigenschaft wird in Vehicle und zeigt auf Driver entfernt.)

modelBuilder.Entity<Vehicle>() 
      .HasRequired(d => d.Driver) 
      .WithRequiredDependent(); 

Sie sind eine obligatorische Beziehung b Angabe somit wischt Vehicle und Driver mit Navigation von Driver zu Vehicle,: Vehicle < 1 - 1 Driver

(. Vehicle ist die abhängige und Driver die Haupt, da die Navigationseigenschaft liegt in Driver zu Vehicle zeigen)

Diese beiden sind analog:

modelBuilder.Entity<Vehicle>() 
      .HasRequired(v => v.Driver) 
      .WithRequiredPrincipal(); 

modelBuilder.Entity<Driver>() 
      .HasRequired(d => d.Vehicle) 
      .WithRequiredDependent(); 
+0

Sehr gute Erklärung. Vielen Dank. –

3

EF erstellt die Vehicle_VehicleId Spalte, weil Sie VehicleId und Vehicle auf Ihrer Driver Entität haben.

Entfernen VehicleId und Vehicle von Ihrem Driver Entity:

public class Driver 
{ 
    public int Id { get; set; } 
    public String Name { get; set; } 
} 

public class Vehicle 
{ 
    public int Id { get; set; } 
    public String Name { get; set; } 
} 

Verwendung:

modelBuilder.Entity<Vehicle>() 
     .HasRequired(d => d.Driver) 
     .WithRequiredPrincipal(); 

Sie setzen die Beziehung so dass keine Notwendigkeit schließen manuelle Eigenschaften in Ihren Entitätsklassen.

Sie erhalten die VehicleId von der Navigationseigenschaft Vehicle:

IQueryable<int> vehicleIds = context.Drivers.Select(x => x.Id == 123).Vehicles.Id; 
+0

Ich habe es entfernt, aber es erstellt immer Vehicle_VehicleId. Nicht die VehicleId in der Treibertabelle. –

+0

Es ist, weil Sie die fließende API verwenden, um Beziehungen zu definieren. Ich habe meine Antwort aktualisiert. Entfernen Sie auch die virtuellen Eigenschaften. –