2013-02-16 60 views
0

假設我每天都要在數據庫中插入數十萬條記錄。其中大約一半已經存在於數據庫中。另外一個獨特的行使用6列進行定義。在.NET中正確處理數據庫中的重複行

在這種特殊情況下,.NET中插入代碼的正確方法是什麼?我想知道的兩個是:

SQL是否直接插入並捕獲重複條目的SQLException?在這種情況下,我打破了Exceptions只應用於特殊情況而非常見情況的概念。

辦一個SQL-選擇首先檢查該行我做一個插入之前?在這種情況下,儘管剛剛完成選擇,數據庫似乎會自動進行插入並自動檢查唯一性。

+0

你在使用,ado.net/ef/stored程序/聯SQL? – 2013-02-16 10:54:26

回答

0

我想你應該選擇異常的方式。只要做這樣的事情:

foreach(var elem in elemntsFromFile) 
{ 
    try 
    { 
     context.sometable.Add(elem); 
     context.SaveChanges(); 
    } 
    catch 
    { 
    } 
} 

有一刻。我非常喜歡db.saveChanges在每次迭代中運行,但它將在100%的性能上比「先選擇的方式」更好。它會工作和工作。

1

使用sql語句在插入之前檢查行。下面是一個表叫人一個簡單的例子,有兩列,名字及姓氏被檢查的獨特性:

/// <summary> 
/// Insert a row into the person table 
/// </summary> 
/// <param name="connection">An open sql connection</param> 
/// <param name="forename">The forename which will be inserted</param> 
/// <param name="surname">The surname which will be inserted</param> 
/// <returns>True if a new row was added, False otherwise</returns> 
public static bool InsertPerson(SqlConnection connection, string forename, string surname) 
{ 
    using (SqlCommand command = connection.CreateCommand()) 
    { 
     command.CommandText = 
      @"Insert into person (forename, surname) 
       Select @forename, @surname 
       Where not exists 
        (
         select 'X' 
         from person 
         where 
          forename = @forename 
          and [email protected] 
        )"; 
     command.Parameters.AddWithValue("@forename", forename); 
     command.Parameters.AddWithValue("@surname", surname); 

     int rowsInserted = command.ExecuteNonQuery(); 

     // rowsInserted will be 0 if the row is already in the database 
     return rowsInserted == 1; 
    } 
} 
+0

您不想爲每個插入打開一個連接。 – CodeCaster 2013-02-16 11:31:37

+0

代碼示例是最簡單的工作。大量的優化是可能的;我的目標是簡潔地展示所有必需的概念,以便任何看到此答案的人都能夠使用它。 – sga101 2013-02-16 11:39:46

+0

我修改了代碼示例,以便它需要一個開放連接,而不是像CodeCaster – sga101 2013-02-16 12:01:27

0

一個簡單的方法忽略重複是創建與選項IGNORE_DUP_KEY = ON唯一索引。您不會因此承擔重複測試或捕獲異常的開銷。

例如

CREATE UNIQUE NONCLUSTERED INDEX [IX_IgnoreDuplicates] ON [dbo].[Test] 
(
    [Id] ASC, 
    [Col1] ASC, 
    [Col2] ASC 
) 
WITH (IGNORE_DUP_KEY = ON) 

您也可以再使用BULK INSERT有效地加載所有數據的自動刪除重複。

CREATE INDEX