2016-07-22 7 views
1

Ich versuche, eine 1-zu-1-Zuordnung in Entity Framework und ein Beispiel zu tun, fand ich online was here, look for the 'Configure One-to-One relationship using Fluent API section'Entity Framework 1-zu-1-Beziehung keine Ausnahme auslösen, wenn abhängige Einheit null ist

Die meisten der Beispiele online ist ähnlich wie der Link ... auch in einigen Büchern, die ich gelesen habe, als ich versuchte, dies zu implementieren.

Hier meine Einheiten sind:

public class Student 
{ 
    public Student() { } 

    public int StudentId { get; set; } 
    public string StudentName { get; set; } 

    public virtual StudentAddress Address { get; set; } 

} 
public class StudentAddress 
{ 
    public int StudentId { get; set; } 

    public string Address1 { get; set; } 
    public string Address2 { get; set; } 
    public string City { get; set; } 
    public int Zipcode { get; set; } 
    public string State { get; set; } 
    public string Country { get; set; } 

    public virtual Student Student { get; set; } 
} 

Mein Datenkontext, die Konfiguration mit dem fließend api umfasst:

public class DataContext : DbContext 
{ 
    public DbSet<Student> Student { get; set; } 

    // public DbSet<StudentAddress> Addresses { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // Configure StudentId as PK for StudentAddress 
     modelBuilder.Entity<StudentAddress>() 
      .HasKey(e => e.StudentId); 

     // Configure StudentId as FK for StudentAddress 
     modelBuilder.Entity<Student>() 
        .HasRequired(s => s.Address) 
        .WithRequiredPrincipal(ad => ad.Student); 

    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (var context = new DataContext()) 
     { 
      var student = new Student { StudentName = "sample name" }; 
      context.Student.Add(student); 
      context.SaveChanges(); 
     } 
      Console.ReadKey(); 
    } 
} 

in der Konsolenanwendung erwarte ich, dass es eine Ausnahme auslösen, da ein Schüler haben muss eine StudentAddress, damit sie gespeichert wird, aber wenn ich die Anwendung ausgeführt und die Datenbank überprüft habe, wurde der Schülereintrag tatsächlich gespeichert. Ich könnte etwas unter der Haube vermissen ... wenn ich jedoch versuche, das [Required] -Attribut oberhalb der StudentAddress-Eigenschaft der Student-Klasse hinzuzufügen, löst es eine Exception aus, wenn ich keine StudentAddress für eine Student-Entität bereitstelle.

Ihr Feedback/Ihre Hilfe wäre sehr hilfreich und würde sehr geschätzt werden. Vielen Dank!

+1

Sie haben es rückwärts. Eine StudentAddress muss einen Studenten haben. Wenn zum Erstellen eines Schülers eine StudentAddress erforderlich ist, liegt ein Problem vor, da StudentID zum Erstellen einer StudentAddress benötigt wird. Wenn beide ausgefüllt werden müssen und die Beziehung 1 zu 1 ist, sollte es wahrscheinlich nur eine einzige Tabelle sein.In Wirklichkeit sollte jede Art von Personen-/Adressbeziehung eine 1 zu viele Beziehung sein, da es viele Leute mit mehr als 1 Adresse gibt. –

+0

Sieht so aus, als ob die Validierung nicht mit Fluent API konfiguriert werden kann. –

+0

@DavidCram Nein, was ich versuche zu tun ist, beide Enden benötigt ... bedeutet, dass Sie nicht einen Studenten ohne eine Adresse einfügen können oder umgekehrt (obwohl es nur in EF ist, weil Sie das nicht in SQL tun können) Wie auch immer, was passiert, wenn Sie SaveChanges aufrufen, wird eine Ausnahme ausgelöst? –

Antwort

1

Ich legte einen Bug Das EF-Team und hier ist die Erklärung, warum es sich so verhält.

https://github.com/aspnet/EntityFramework6/issues/66#issuecomment-248073084

Von Arthur Vickers (Mitglied des EF Entwicklerteam):

EF werden Sie immer einen neuen Haupt (Student in Ihrem Modell) lassen einfügen ohne Angehörigen unabhängig davon, ob die Beziehung ist erforderlich oder nicht. Eine erforderliche Beziehung bedeutet, dass eine abhängige (Adresse in Ihrem Modell) nicht ohne einen entsprechenden Principal eingefügt werden kann. Ich weiß, dass die Art und Weise, wie Beziehungen in EF6 modelliert werden, etwas anderes bedeutet, aber die Entscheidung, Beziehungen auf diese Weise zu beschreiben und sich dann so zu verhalten, wurde vor vielen Jahren getroffen und wir können es jetzt nicht ändern.

0

Versuchen Sie, die Deklaration für das Hauptende der Beziehung zu entfernen. Nach meiner Erfahrung, dass nur dann, wenn Sie Annotations verwenden benötigt wird/Attribut 1-1 Beziehungen zu erstellen:

modelBuilder.Entity<Student>() 
    .HasRequired(s => s.Address); 
+0

mein Punkt genau ... es sollte 1-1 sein, was bedeutet, dass Sie keine Entität ohne die andere speichern können. (Zumindest in Entity Framework, wenn Sie SaveChanges aufrufen) –

+0

Ich erwarte, dass es eine Ausnahme wirft ... würde es hinzufügen ein erforderliches Attribut für die Navigationseigenschaft der Entitäten. hmmmmm :) –

+1

Wie es steht, erstellt die obige Änderung eine Fremdschlüsseleinschränkungsverletzung und löst daher eine Ausnahme aus, wenn Sie versuchen, einen Student ohne eine StudentAddress hinzuzufügen. Da Sie das DBSet für Adressen auskommentiert haben, können Sie keine StudentAddress hinzufügen, ohne einen Student zu erstellen und die StudentAddress dem neuen Student hinzuzufügen, bevor Sie speichern. Können Sie erklären, dass dies Ihre Bedürfnisse nicht erfüllt? (Dies verwendet übrigens keine Anmerkungen, wie Sie es gewünscht haben.) –

0

in einer Eins-zu-Eins-Beziehung eines Ende muss Haupt- und zweites Ende sein muss abhängig sein. Das Hauptende ist dasjenige, das zuerst eingefügt wird und das ohne das abhängige Ende existieren kann. Abhängiges Ende ist dasjenige, das nach dem Principal eingefügt werden muss, da es einen Fremdschlüssel für den Principal hat.

So versuchen, diese entfernen:

.WithRequiredPrincipal(ad => ad.Student); 

für

.WithRequiredDependent(ad => ad.Student); 

oder Sie können diese Zeile entfernen oder [Required] Datenaufbelichtung auf dem Grundstück nutzen ...

+0

naja ... das Ziel ist es tatsächlich erreicht, ohne Datenannotationen zu verwenden. erneut ... Ich erwarte, dass mein Code eine Ausnahme auslöst, da beide Entitäten erforderlich sind. Wenn Sie also SaveChanges aufrufen, sollte die Ausnahme ähnlich ausgelöst werden, wenn ich ein erforderliches Attribut für beide Navigationseigenschaften meiner Entitäten hinterlasse. –

+0

ok, hast du folgendes versucht: 'modelBuilder.Entity () .HasKey (e => e.StudentId) .HasRequired (s => s.Student); modelBuilder.Entity () .HasRequired (s => s.Address); ' –

+0

, dass ein erzeugen würde, die es heißt, könnte die Haupt Assoziation zwischen den Entitäten nicht bestimmen. –

Verwandte Themen