Пакетное обновление Linq-To-Sql с дубликатами

Я обновляю базу данных с LINQ-To-SQL в C# .NET 3.5, но данные, которые я использую, не всегда хороши. Есть хорошая вероятность, что будут дубликаты от вставленных данных и базы данных.

На данный момент я использую это, где dataSetOne , dataSetTwo и dataSetThree - список обновляемых моделей:

AppDataContext db = new AppDataContext();

db.DatasetOne.InsertAllOnSubmit(dataSetOne);
db.DatasetTwo.InsertAllOnSubmit(dataSetTwo);
db.DatasetThree.InsertAllOnSubmit(dataSetThree);

try
{
    db.SubmitChanges(ConflictMode.ContinueOnConflict);
}

catch (Exception e)
{
    CsvToImsConverter.Log.Error(e.Message);

    foreach (ObjectChangeConflict occ in db.ChangeConflicts)
    {
        MetaTable metatable = db.Mapping.GetTable(occ.Object.GetType());
        Console.WriteLine("Error in Table: {0}", metatable.TableName);
    }
}

И это прекрасно работает. Проблема в том, что если есть дубликаты, программа не обновляется, бросая нарушение первичного ключа. Я хочу вставить значения, которые не имеют нарушения первичного ключа, и обновить те, которые этого не делают.

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

Будет ли я лучше использовать цикл foreach и вставить каждый объект в список с помощью инструкции catch ?

Заранее спасибо.

2
nl ja de
пытались ли вы проверить чек на наличие, чтобы увидеть, насколько сильно вы достигли производительности, которую вы на самом деле получаете? Думая о преждевременной оптимизации корня зла и всего этого ... что-то вроде этого stackoverflow.com/questions/100068/…
добавлено автор Terrance, источник
переместите попытку поймать вокруг вставки ....
добавлено автор Mitch Wheat, источник
Вставки отлично работают, поскольку они не обновляют базу данных. Это SubmitChanges, который бросает исключение.
добавлено автор Irish Yobbo, источник
Это то, что я собирался сделать, но я решил проверить, есть ли лучший способ. Вероятно, будет только 2-3 объекта с дубликатами, а разбор тысяч в db для такого небольшого числа кажется довольно неэффективным.
добавлено автор Irish Yobbo, источник

1 ответы

Вы беспокоитесь о производительности и в то же время используете Linq-2-sql для пакетных вставок/обновлений. Это не очень непротиворечиво, так как linq-2-sql не подходит для пакетных операций (по крайней мере, если вам нужно, чтобы они были быстрыми).

Не обманывайте InsertAllOnSumbit ... Linq-2-sql создаст отдельный оператор insert для каждой вставки. Это уже само по себе очень медленно.

Вы намного лучше загружаете свой набор данных One/Two/Three в промежуточной таблице (например, используя SqlBulkCopy), и после этого используйте оператор слияния, чтобы перейти к вашей целевой таблице.

1
добавлено
Спасибо за совет, я посмотрю.
добавлено автор Irish Yobbo, источник
Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

SqlCom.ru - Стиль жизни SQL
SqlCom.ru - Стиль жизни SQL
908 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только MS SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz). Предложения в @sql_ninja

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot

SQL_Ninja
SQL_Ninja
340 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz)