2016-05-31 81 views
0

我在插入重複記錄時遇到了非常奇怪的情況。 我正在根據特定條件檢索記錄,並且在修改了幾個屬性之後,我再次重新插入整個對象集合,甚至不更改對象的主鍵值。如何在實體框架中插入重複記錄

但我沒有得到預期的結果。嵌套在父集合中的所有集合都不會完全添加到數據庫中。

我不知道怎麼回事。我是否需要完全分離所有這些實體? 我已經使用NoTracking()檢索實體,甚至在修改它的屬性時分離父實體。

我父母收集貨物及載有兒童實體名單 「ConsignmentLine」

我的實體層次結構是:參與我的代碼

public class Consignment 
{ 
    public int ConsignmentId { get; set; } 
    public int ClientSubsidiaryId { get; set; } 
    public int ForwarderId { get; set; } 
    public int ClientId { get; set; } 

    public ICollection<ConsignmentLine> ConsignmentLines { get; set; }  

    public Consignment() 
    {   
     ConsignmentLines = new List<ConsignmentLine>();    
    } 
} 

public class ConsignmentLine 
{ 
    public int ConsignmentLineId { get; set; } 
    public int PackagingId { get; set; } 
    public double Amount { get; set; } 
    public double Weight { get; set; }     

    public int ConsignmentId { get; set; } 
    public virtual Consignment Consignment { get; set; }   
} 

步驟:

檢索數據:

var Consignments = _dbContext.Consignments.AsNoTracking().Where(Pr => (Pr.SourceParty == 0 && Pr.ParentId == null && Pr.ConnectState>=4)).ToList(); 

修改幾個屬性。

consignments.ForEach(
      (consignment) => 
      { 
       consignment.ClientId = clientId;      
       _dbContext.Entry(consignment).State = System.Data.Entity.EntityState.Detached; 
       consignment.ForwarderId = forwarderId; 
       consignment.ClientSubsidiaryId = clientSubsidiaryId;      
      }); 

試圖保存塊,因爲我知道,託運有> 250000條記錄。

const int BulkSize = 1000; 
var SkipSize = 0; 

try 
{                               
    while (SkipSize < consignments.Count) 
    { 
     ProcessableConsignments = consignments.Skip(SkipSize).Take(BulkSize).ToList();                                     _dbContext.Configuration.AutoDetectChangesEnabled = false;  
           dbContext.Consignments.AddRange(ProcessableConsignments); 

     var changedRecords = _dbContext.SaveChanges(); 
     SkipSize = SkipSize + BulkSize;            
     }          
} 
catch (Exception ex) 
{ 
    throw; 
} 

我不知道我在這裏失蹤。 我需要重新插入包含各種其他子實體的記錄的整個BULK作爲第二次收集(實際上是循環中的N次)作爲新的BULK。

+0

如果你將刪除這個:_dbContext.Entry(寄存).State = System.Data.Entity.EntityState.Detached; –

+1

你是否嘗試設置ConsignmentId = 0? –

+0

太棒了:以前我在嘗試ConsignmentId = -1,但這是完全修改和重置內部子實體(即ConsignmentLines)和ConsignmentLines重新初始化。 所以,現在我沒有費心觸摸ConsignmentId – Usman

回答

0

我相信,當您將已分離的實體從上下文中分離出來時,您可以有效地指示上下文在添加回上下文時忽略這些實體。 此外,我強烈建議您不要因性能原因而在批量更新中使用EF。在其他情況下,至少爲每個交易創建新的上下文,每個下一批次的處理時間將會增長。

+0

Vitaliy Kalinin:我沒有修改實體。我正在插入新的實體。但是我重新使用了已經檢索到的實體的99%的舊數據。這就是爲什麼我不想通過在內存中再次創建整個集合來製作帶有嵌套子節點的220000條記錄的新副本。這就是原因,我只是用我提供的值修改了幾個退出的字段。在插入這些實體(那些不是新創建的)之後,我希望實體框架將它們全部插入爲新實體,並將返回新的主鍵。 – Usman

+0

關於批量插入..我知道實體框架的這種限制。我打算用EntityFramework.BulkInsert(CodePlex)替換。但是現在我想繼續這個實現。 這就是爲什麼我只保存1000個記錄的批量修改。 – Usman