[英]EF6 Many to many Insert
我的问题是使用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会成功创建关系表和合同。 在第二辆车的保存失败说“ 约束失败UNIQUE约束失败:Contracts.ContractId”,因为我想插入一个Contract
具有相同Id
为已经存在的合同。
我发现此问题的解决方案是将dbContext
的Contract
设置为Attached:
foreach (var contract in car.Contracts)
{
context.Contract.Attach(contract);
}
这将引发与先前保存相同的异常。 当我尝试修改第二辆汽车的合同清单时,我得到一个NotSupportedException
,我能想到的唯一解决方案是重新创建汽车对象并将相同的Contract对象附加到它们,这似乎不必要地复杂。
有没有办法告诉EF我的两个不同的合同对象实际上是相同的?
有没有办法告诉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}));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.