在Entity Framework 4.2中,我有一个Trips实体,可以有0 .. * PlacesOfInterest和0 .. *照片。景点有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 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;
}
}
由于
取值
答案 0 :(得分:1)
此...
context.Trips.Include("PlacesOfInterest")....
...将加载行程中的PlacesOfInterest
。当您将旅程附加到其他上下文trip.PlacesOfInterest
时也会附加。因为您之前已经附加了PlaceOfInterest
(在集合中具有PlaceOfInterest
的Id),所以您将使用相同的键附加两个相同类型的对象。这会导致异常。
您实际上可以简化代码:您不需要加载实体,因为您拥有主键。然后,您可以使用该密钥创建新实例并附加它:
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);