实体框架中的三元关系

本文关键字:三元 关系 框架 实体 | 更新日期: 2023-09-27 18:29:58

在实体框架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;
    }

当我测试这一点时,当连接Trip时,我会得到以下信息:

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

感谢

S

实体框架中的三元关系

这个。。。

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

将加载带有跳闸的CCD_ 1。当您将行程附加到其他上下文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);