2013-12-22 72 views
2

我正在使用LINQ以及Entity-Framework在SQL Server 2012數據庫中插入一些數據。實體框架一次插入多行時忽略重複主鍵值

我正在插入數據的數據庫表有一個主鍵,我一次插入大約1000條記錄。

這是我檢索一組1000行中的數據,並出於性能原因一次保存1000行。

現在的問題是,我可能偶爾會獲得這1000行中的任何行的重複值,當發生這種情況時,沒有任何行保存在數據庫中。

有什麼辦法,我可以只是默默地忽略那一行,而不是插入它,而所有其他非重複行插入?

另外我也嘗試在每次插入之前查詢數據庫,但性能成本太高。

+0

在Sql Table本身中不能有重複的主鍵,因此實體框架無法做到這一點,約束不應該繞過但受到尊重,將用戶操作排隊到可以並行完成的作業中,用戶移動到別的東西上。許多方式來處理這個,而不會忽略數據的完整性 –

回答

0

有什麼辦法可以只是默默地忽略那一行,而不插入它,而所有其他非重複行插入?

如果您可以在SQL Server中重新創建索引,則可以忽略重複項。插入後重新創建索引而不使用ignore_dups,因爲它的速度更快。

CREATE TABLE [dbo].[YourTable](
    [id] [int] NOT NULL, 
PRIMARY KEY CLUSTERED 
(
    [id] ASC 
)WITH (IGNORE_DUP_KEY = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 
0

我建議你在插入語句之前做一些額外的處理,沒有任何代碼離開我會嘗試用僞代碼向你展示。

ICollection<record> myRecords = Service.GetMyRecords(); 
//your processing logic before the insert 
ICollection<record> recordsToInsert =Service.BusinessLogic(myRecords); 

foreach(var record in recordsToInsert) 
{ 
    if(myRecords.Contains(record) 
    { 
     recordsToInsert.Remove(record); 
    } 
} 

這應該可以確保您在recordsToInsert集合中沒有記錄會使您的數據庫跳閘。這也爲您節省了嘗試插入語句,因爲它不會嘗試並失敗。

+0

問題是表有150萬+記錄,並檢查是否有任何記錄是一個耗時的過程。 – FatalTouch

+0

然後我會建議更改DB上的設置以正確處理此問題,因爲這似乎是運行時成本最低的解決方案; user3123649建議了一種方法來做到這一點。 –

0

做一個查詢第一,檢查的新記錄的任何是否存在像這樣:

var checks = records.Select(r => r.Id).ToArray(); 
if (!context.Records.Any(r => check.Contains(r.Id)) 
{ 
    // do the insert 
} 

第一檢查後,你可以細化檢查,以找出其中的1000條記錄是罪魁禍首。所以這個快樂場景總是很快。只有在找到重複的情況下,該過程纔會變慢。

在運行一個事務時,您無法指示EF默默忽略一個數據庫異常。