简体   繁体   中英

Ternary relationships in Entity Framework

In Entity Framework 4.2 I have a Trips entity that can have 0..* PlacesOfInterest and 0..* Photos. Places of Interest has 1 Trip and 0..* Photos. Photos have 1 Trip and 0..1 Places of Interest.

When I try to add a Photo, I use this method:

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

When I test this, I get the following when the Trip is attached:

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

The Trip does appear in the context object, but the PlacesOfInterest does too before the Attach statement. I don't understand how this works, can someone clarify?

EDIT: Here are the POI and Trip Getters

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

Thanks

S

This...

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

...will load the PlacesOfInterest with the trip. When you attach the trip to the other context trip.PlacesOfInterest get attached as well. Because you already have attached a PlaceOfInterest before (which has an Id of a PlaceOfInterest in the collection) you are attaching two objects of the same type with the same key. This causes the exception.

You can actually simplify your code: You don't need to load the entities because you have their primary key. Then you can just create new instances with that key and attach it:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM