2013-02-16 3 views
0

Скажем, у меня есть сотни тысяч записей в текстовом файле, который я хотел бы вставлять в базу данных каждый день. Из них примерно половина из них уже существует в базе данных. Также уникальная строка определяется, используя, скажем, 6 столбцов.правильная обработка повторяющихся строк в базе данных в .NET.

Каков правильный способ кодирования вставки в .NET в данном конкретном случае? Эти два вопроса, которые мне интересны, это:

Я вставляю SQL-код сразу и поймаю SQLException для дубликатов записей? В этом случае я бы нарушил концепцию, согласно которой Исключения должны использоваться только для исключительных случаев, а не для частых случаев.

или

ли я сделать SQL-выбрать первый для проверки строки, прежде чем я делать вставки? В этом случае, похоже, что база данных будет делать вставку и проверять уникальность во второй раз автоматически, несмотря на то, что она только что завершила выбор.

+0

Что вы используете, ado.net/ef/stored процедуру/встроенный SQL? –

ответ

0

Я думаю, вы должны выбрать исключение. Просто сделайте что-нибудь подобное:

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

Один момент. Я dodnt, как и 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

+0

Образец кода - это самая простая вещь, которая будет работать. Возможно много оптимизаций; моя цель состояла в том, чтобы наглядно продемонстрировать все необходимые концепции, чтобы каждый, кто смотрит на этот ответ, сможет использовать его. – sga101

+0

Я изменил образец кода, так что вместо создания открывающего соединения требуется открытое соединение, как это было предложено CodeCaster – sga101

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

Смежные вопросы