C# 实体框架中的三元关系

C# 实体框架中的三元关系,c#,entity-framework,C#,Entity Framework,在实体框架4.2中,我有一个Trips实体,它可以有0..*PlacesOfInterest和0..*Photos。景点有1张旅行和0张..*照片。照片有1次旅行和0..1个景点 当我尝试添加照片时,我使用以下方法: public static Guid Create(string tripId, Model.Photo instance) { var context = new Model.POCOTripContext(); var clean

在实体框架4.2中,我有一个Trips实体,它可以有0..*PlacesOfInterest和0..*Photos。景点有1张旅行和0张..*照片。照片有1次旅行和0..1个景点

当我尝试添加照片时,我使用以下方法:

    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.
Trip确实出现在上下文对象中,但PlacesOfInterest也出现在Attach语句之前。我不明白这是怎么回事,有人能澄清一下吗

编辑:以下是POI和Trip获取者

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

S

context.Trips.Include("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);
这个

context.Trips.Include("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);

我认为您不需要再次附加相关项(我认为只要相关项已经通过setter附加,附加调用就是多余的)。是否尝试不附加?是的,然后它尝试插入。查看此问题:能否在
Library.Trip.Get(…)
Library.PlaceOfInterest.Get(…)
中显示代码?我认为您不需要再次附加相关项(我相信只要相关项已通过setter附加,附加调用是多余的)。是否尝试不附加?是的,然后它尝试插入。查看此问题:能否在
Library.Trip.Get(…)
Library.PlaceOfInterest.Get(…)
中显示代码?