我的问题是在EF6的代码优先数据库中保存现有对象,这些对象是多到多关系的一部分。
我正在接收来自web服务的对象,它们看起来(简化)如下:
public class Car
{
[DataMember]
public virtual string CarId { get; set; }
[DataMember]
public virtual ICollection<Contract> Contracts { get; set; }
}
public class Contract
{
[DataMember]
public virtual string ContractId { get; set; }
[DataMember]
public virtual ICollection<Car> Cars { get; set; }
}我有一个代码优先数据库,并设置了以下关系:
modelBuilder.Entity<Contract>().HasKey(t => new {t.ContractId});
modelBuilder.Entity<Car>().HasKey(t => new {t.CarId})
.HasMany(c => c.Contracts)
.WithMany(c => c.Cars)
.Map(x =>
{
x.ToTable("CarContracts");
x.MapLeftKey("CarId");
x.MapRightKey("ContractId");
});当我得到一个汽车列表,我可以保存第一个汽车和EF创建关系表和合同成功。在第二个car上,保存失败,上面写着“约束失败,唯一约束失败: Contracts.ContractId",因为我试图插入一个与已经存在的合同具有相同Id的Contract。
我找到的解决这个问题的方法是将dbContext中的dbContext设置为附件:
foreach (var contract in car.Contracts)
{
context.Contract.Attach(contract);
}这将引发与上次保存相同的异常。当我试图修改第二辆车的合同列表时,我得到了一个NotSupportedException,我能想到的唯一解决方案就是重新创建汽车对象并将相同的合同对象附加到它们上,这似乎是不必要的复杂。
有没有办法告诉EF,我的两个不同的合同对象实际上是相同的?
发布于 2016-02-19 09:01:38
有没有办法告诉EF,我的两个不同的合同对象实际上是相同的?
唯一的办法是,它们实际上是同一个物体。如果它们是不同的实例,即使拥有所有相同的数据,EF也不会将它们识别为同一个实体。
因此,唯一的解决方案是将所有相同的id契约实例替换为一个单独的实例。
或者更简单:创建一个表示N:N关系的显式实体,然后简单地构建一个列表以插入如下:
var toInsert = new List<CarContract>();
foreach(var car in cars)
{
toInsert.AddRange(car.Select(x=>new CarContract {CarId=car.Id,ContractId=x.Id}));
}https://stackoverflow.com/questions/35500392
复制相似问题