2016-02-19 49 views
0

我的問題是使用EF6在代碼優先的數據庫中保存作爲多對多關係一部分的現有對象。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」,因爲我試圖插入ContractId作爲已有的合同。

,我發現這個問題的解決方案是設置ContractdbContext附:

foreach (var contract in car.Contracts) 
{ 
    context.Contract.Attach(contract); 
} 

這將引發同樣的異常與先前保存。當我嘗試修改第二輛車的合同列表時,我得到一個NotSupportedException,我能想到的唯一解決方案是重新創建汽車物件並將相同的合同對象附加到它們上面,這似乎不必要的複雜。

有什麼方法可以告訴EF我的兩個不同的合同對象實際上是相同的嗎?

+0

? – tede24

+0

通過WCF服務,所以我沒有自己創建它們 – user613068

+0

你能解釋爲什麼第二次插入必須與現有的汽車和合同組合?錯誤消息明確指出它違反了Contracts表中的UNIQUE約束。 – user613068

回答

1

有什麼方法可以告訴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})); 
}