2013-01-13 7 views
7

Ich möchte Entity Framework POCO in einem getrennten (aus Kontext) -Modus verwenden. In meinem Szenario erstelle ich ein neues Eltern-Objekt und möchte ein vorhandenes Kind-Objekt anhängen und dann in der Datenbank speichern.
Der folgende Code fügt in unerwünschter Weise einen neuen Kursdatensatz ein, wenn ein neuer Schülerdatensatz gespeichert wird. Stattdessen möchte ich den vorhandenen Kursdatensatz mit dem neuen Schülerdatensatz verknüpfen.Entity Framework: Hinzufügen vorhandener untergeordneter POCO zu neuem übergeordneten POCO, Erstellen eines neuen untergeordneten Elements in DB

Wie kann ich dies tun in Entity Framework, wo ...

  • die Objekte aus dem Kontext getrennt werden. (d. h. in einem Kontext abgefragt und dann in einem anderen Kontext gespeichert)
  • Ich muss den untergeordneten Datensatz nicht erneut aus der DB abfragen, nur damit ich ihn an den übergeordneten anhängen kann, wenn ich in db speichere. Ich möchte wirklich vermeiden, extra Fahrten zum db zu machen, wenn ich es bereits als ein Objekt im Speicher habe.

Diese Seite zeigt eine Datenbank-Diagramm, das die folgenden Code auf http://entityframeworktutorial.net/EF4_EnvSetup.aspx#.UPMZ4m-UN9Y

class Program 
{ 
    static void Main(string[] args) 
    { 

     //get existing course from db as disconnected object 
     var course = Program.getCourse(); 

     //create new student 
     var stud = new Student(); 
     stud.StudentName = "bob"; 

     //assign existing course to the student 
     stud.Courses.Add(course); 

     //save student to db 
     using (SchoolDBEntities ctx = new SchoolDBEntities()) 
     { 
      ctx.Students.AddObject(stud); 
      ctx.SaveChanges(); 
     } 
    } 

    static Course getCourse() 
    { 
     Course returnCourse = null; 

     using (var ctx = new SchoolDBEntities()) 
     { 
      ctx.ContextOptions.LazyLoadingEnabled = false; 
      returnCourse = (from s in ctx.Courses 
          select s).SingleOrDefault(); 
     } 

     return returnCourse; 
    } 
} 

Antwort

17

Ich glaube, es gibt einige Möglichkeiten, dies zu erreichen. können Sie festlegen, dass natürlich Einheit unverändert ist, anstatt hinzugefügt, in diese Richtung:

ctx.Entry(course).State = EntityState.Unchanged; 

Oder Ihr Kontext anweisen, dass Sie mit den bestehenden Unternehmen arbeiten:

ctx.Courses.Attach(course); 

Mehr Infos hier: http://msdn.microsoft.com/en-us/data/jj592676.aspx

EDIT

Es gibt einige laufende Beispiele von meiner Lösung, ich verifizierte, dass sie wie erwartet funktionieren. In allen Fällen haben wir Publisher Datensatz in der Datenbank mit ID = 2 und Name = "Addison Wesley" (irrelevant für das Beispiel, aber nur für das gute Maß).

Ansatz 1 - Einstellung Entitätsstatus

using (var context = new Context()) 
{ 
    var book = new Book(); 
    book.Name = "Service Design Patterns"; 
    book.Publisher = new Publisher() {Id = 2 }; // Only ID is required 
    context.Entry(book.Publisher).State = EntityState.Unchanged; 
    context.Books.Add(book); 
    context.SaveChanges(); 
} 

Ansatz 2 - Bringen Unter Verwendung der Methode

using (var context = new Context()) 
{ 
    var book = new Book(); 
    book.Name = "Service Design Patterns";     
    book.Publisher = new Publisher() { Id = 2 }; // Only ID is required 
    context.Publishers.Attach(book.Publisher); 
    context.Books.Add(book); 
    context.SaveChanges(); 
} 

Ansatz 3 - Einstellen der Fremdschlüsselwert

using (var context = new Context()) 
{ 
    var book = new Book(); 
    book.Name = "Service Design Patterns"; 
    book.PublisherId = 2; 
    context.Books.Add(book); 
    context.SaveChanges(); 
} 

Für diesen letzten Ansatz zur Arbeit ich zusätzliche Eigenschaft PublisherId hinzufügen benötigen, hat es nach NavigationPropertyName + ‚Id genannt werden“ Konvention auotmatically von EF abgeholt werden:

public int PublisherId { get; set; } 
public Publisher Publisher { get; set; } 

ich hier EF5-Code verwenden Erstens, aber es ist sehr ähnlich zu POCO.

+0

Die zweite Option funktioniert fast, aber ich bekomme ein "Das Objekt kann nicht angefügt werden, da es bereits im Objektkontext ist." Fehler beim "ctx.Students.AddObject (Stud)" Linie. Ich nehme an, ich kann das nicht tun, während ich noch "stud.Courses.Add (course) mache"; bevor . Ich möchte immer noch die Courses-Kollektion im Stud-Objekt nutzen. – MakkyNZ

+0

Nun, ich habe keine praktische Lösung, um es zu testen, aber versuche es zuerst anzuhängen und dann dem Schüler hinzuzufügen. Hoffentlich wird es nicht als "Hinzugefügt" von EF markiert. –

+0

das ist nicht wirklich ideal. Ich möchte, dass die Eltern-Kind-Beziehung zuerst auf Objektebene stattfindet, da sie möglicherweise noch nicht bereit ist, in db zu speichern. Vielleicht sollte ich einfach alle Beziehungen zwischen den Entitäten, die EF generiert, entfernen und diese selbst manuell steuern? – MakkyNZ

0

Entity Framework basiert nicht Beziehungen erlauben, die Zusammenhänge durchqueren.

Wenn Sie das Lesen des Kurses platzieren und den Kurs mit dem Kursteilnehmer innerhalb derselben using-Anweisung verbinden, würde es funktionieren.

0

Ich versuchte auch die zweite Option, die es für mich arbeitete. Ich mochte die Eltern-Kind-Beziehung, die zuerst auf Objektebene passiert und dann in db speichert. Vielleicht sollte ich einfach alle Beziehungen zwischen den Entitäten, die EF generiert, entfernen und diese selbst manuell steuern.

Verwandte Themen