2012-04-02 14 views
1

In Entity Framework 4.2 Ich habe eine Trips-Entität, die 0 .. * OrteOfInterest und 0 .. * Fotos haben kann. Orte von Interesse hat 1 Trip und 0 .. * Fotos. Fotos haben 1 Trip und 0..1 Sehenswürdigkeiten.Ternäre Beziehungen in Entity Framework

Wenn ich ein Foto hinzuzufügen, verwende ich diese Methode:

public static Guid Create(string tripId, Model.Photo instance) 
    { 
     var context = new Model.POCOTripContext(); 
     var cleanPhoto = new Model.Photo(); 
     cleanPhoto.Id = Guid.NewGuid(); 
     cleanPhoto.Name = instance.Name; 
     cleanPhoto.URL = instance.URL; 
     //Relate the POI 
     cleanPhoto.PlaceOfInterest = Library.PlaceOfInterest.Get(instance.PlaceOfInterestId); 
     context.PlacesOfInterest.Attach(cleanPhoto.PlaceOfInterest); 
     //Relate the trip 
     cleanPhoto.Trip = Library.Trip.Get(new Guid(tripId)); 
     context.Trips.Attach(cleanPhoto.Trip); 
     //Add the photo 
     context.Photos.AddObject(cleanPhoto); 
     context.SaveChanges(); 
     return cleanPhoto.Id; 
    } 

Wenn ich dies zu testen, erhalte ich die folgende, wenn die Reise verbunden ist:

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key. 

Die Reise erscheint im Kontext-Objekt, aber die PlacesOfInterest auch vor der Attach-Anweisung. Ich verstehe nicht, wie das funktioniert, kann jemand klären?

EDIT: Das Hier sind die POI und Reise Getter

public static Model.Trip Get(Guid tripId) 
    { 
     using (Model.POCOTripContext context = new Model.POCOTripContext()) 
     { 
      var tripEntity = context.Trips.Include("PlacesOfInterest").Include("PlacesOfInterest.PoiAttributes").Include("Photos").FirstOrDefault(c => c.Id == tripId) ?? new Model.Trip(); 
      return tripEntity; 
     } 
    } 

    public static Model.PlaceOfInterest Get(Guid poiId) 
    { 
     using (Model.POCOTripContext context = new Model.POCOTripContext()) 
     { 
      var poiEntity = context.PlacesOfInterest.Include("PoiAttributes").FirstOrDefault(c => c.Id == poiId) ?? new Model.PlaceOfInterest(); 
      return poiEntity; 
     } 
    } 

Dank

S

+0

Ich glaube nicht, Sie wieder die zugehörige Artikel anhängen müssen (ich glaube, der Ruf anhängen ist überflüssig, solange die zugehörige Artikel sind bereits angebracht über die Setter). Hast du es ohne Attach versucht? –

+0

Ja, dann versucht es zu Einfügen. Siehe diese Frage: http://stackoverflow.com/questions/9915216/why-does-adding-a-child-element-to-my-entity-framework-try-and-insert-a-new-pare –

+0

Können Sie Zeigen Sie den Code in 'Library.Trip.Get (...)' und 'Library.PlaceOfInterest.Get (...)'? – Slauma

Antwort

1

...

context.Trips.Include("PlacesOfInterest").... 

... lädt das PlacesOfInterest mit der Ausflug. Wenn Sie den Trip an den anderen Kontext anhängen, erhalten Sie auch trip.PlacesOfInterest. Da Sie bereits eine PlaceOfInterest angehängt haben (die eine ID von PlaceOfInterest in der Sammlung hat), verbinden Sie zwei Objekte des gleichen Typs mit demselben Schlüssel. Dies verursacht die Ausnahme.

Sie können Ihren Code tatsächlich vereinfachen: Sie müssen die Entitäten nicht laden, weil Sie ihren Primärschlüssel haben. Dann können Sie einfach neue Instanzen mit diesem Schlüssel erstellen und fügen Sie es:

cleanPhoto.PlaceOfInterest = new PlaceOfInterest 
          { Id = instance.PlaceOfInterestId }; 
context.PlacesOfInterest.Attach(cleanPhoto.PlaceOfInterest); 

cleanPhoto.Trip = new Trip { Id = new Guid(tripId) }; 
context.Trips.Attach(cleanPhoto.Trip); 
+0

Perfekt, danke! Ich habe etwas gelernt! –

Verwandte Themen