2012-04-02 67 views
1

在Entity Framework 4.2中,我有一個Trips實體,它可以有0 .. * PlacesOfInterest和0 .. * Photos。景點有1個旅行和0 .. *照片。照片有1個旅程和0..1個景點。Entity Framework中的三元關係

當我嘗試添加照片,我用這個方法:

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; 
    } 

當我測試,我得到以下時,跳閘附:

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

的旅行確實出現在上下文對象中,但是PlacesOfInterest也在Attach語句之前。我不明白這是如何工作的,有人可以澄清?

編輯:這裏是POI和旅行吸氣劑

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; 
     } 
    } 

感謝

小號

+0

我不認爲你需要再次附上相關項目(我相信連接呼叫是多餘的,只要相關的項目已經連接通過setters)。你沒有連接試試嗎? – 2012-04-02 19:25:22

+0

是的,然後它試圖插入。看到這個問題:http://stackoverflow.com/questions/9915216/why-does-adding-a-child-element-to-my-entity-framework-try-and-insert-a-new-pare – 2012-04-02 19:33:42

+0

你能在'Library.Trip.Get(...)'和'Library.PlaceOfInterest.Get(...)'中顯示代碼? – Slauma 2012-04-02 20:19:27

回答

1

這...

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

...將加載PlacesOfInterest與行程。當您將行程附加到其他上下文trip.PlacesOfInterest時也會被附加。因爲您之前已經附加了PlaceOfInterest(集合中的Id爲PlaceOfInterest),所以您使用相同的密鑰附加了兩個相同類型的對象。這導致異常。

你實際上可以簡化你的代碼:你不需要加載實體,因爲你有他們的主鍵。然後,你可以創建與關鍵的新實例,並重視它:

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

完美,謝謝!我學到了東西! – 2012-04-02 21:10:54