EF Core 3.0: дубликат вставки с огромным количеством данных - PullRequest
0 голосов
/ 17 октября 2019

Я использую EF Core с .NET Core 3.0. Я сталкиваюсь с очень странным случаем. Я передаю данные из SQLite в SQL Server.

using (var context1 = new Context1())
using (var context2 = new Context2())
{
    foreach(var tran in context1.Transactions.Distinct())
    {
        var trans = new Model{
            PersonID = tran.PersonID,
            CreatedDate = tran.TranDate,
            TranDate = tran.TranDate,
            CreatedBy = tran.CreatedBy
        };
        context2.Transactions.Add(trans);

    }

    int cc = context2.SaveChanges();
    int count1 = context1.Transactions.Count();
    int count2 = context2.Transactions.Count();
}

Проблема заключается в том, что при вставке небольшого объема данных (1000 строк) целостность данных нормальная, но при одновременной вставке 200 000 записей данные дублируются, но количество записей, которые следует вставитьправильно.

Также я заметил, что дубликаты происходят в разных циклах, поскольку их идентификаторы не в последовательности, а вставки происходят случайным образом!

ID      TranDate                   PersonID CreatedBy CreatedDate 
-------------------------------------------------------------------------------    
513842  2019-06-17 10:29:11.3368419 93596   NULL    2019-06-17 10:29:11.3368419 
516055  2019-06-17 10:29:11.3368419 93596   NULL    2019-06-17 10:29:11.3368419 
516342  2019-06-17 10:29:11.3368419 93596   NULL    2019-06-17 10:29:11.3368419

ОБНОВЛЕНИЕ: просто для подтверждения дубликатов

Данные SQLite

enter image description here

SqlServer:

enter image description here

Update2:

Console.WriteLine(context1.Transactions.OrderBy(t => t.TranDate).GroupBy(t => t.TranDate).Count());

194735

Однако;

foreach(var tran in context1.Transactions.OrderBy(t => t.TranDate).AsEnumerable().GroupBy( x => x.TranDate).Select(g => g.First()))

общее число, переданное SqlServer, составляет

enter image description here

Ответы [ 3 ]

0 голосов
/ 17 октября 2019

Массовая вставка лучше подходит, когда число строк находится в диапазоне 200 000.

Если вам не нужна целостность транзакций, вы можете вставлять их порциями по 1000 или 5000 строк за раз.

0 голосов
/ 18 октября 2019

Я думаю, что проблема может быть связана с дублированием контекста БД. Поскольку обе структуры БД практически одинаковы, я продублировал существующий контекст БД и изменил строки подключения. это должно быть что-то внутри, все еще ссылаясь друг на друга ?! Я не знаю. Проблема появляется только после трех тысяч записей.

Однако для решения этой проблемы я удалил все файлы, связанные с контекстом БД, включая модели, и создал новые, используя команды scaffold для каждой базы данных

dotnet ef dbcontext scaffold "Data Source=data.db" Microsoft.EntityFrameworkCore.Sqlite --output-dir Models

dotnet ef dbcontext scaffold "connectionstring" Microsoft.EntityFrameworkCore.SqlServer --output-dir Models

результат Iв данных не было дубликатов, но они не были вставлены по порядку, и, похоже, нормальное поведение EF.

0 голосов
/ 17 октября 2019

Я думаю, проблема в том, что Distinct() не делает то, что вы думаете, что делает.

Я подозреваю, что в исходной таблице есть «дубликаты» с разными идентификаторами.

Я предлагаю вам использовать GroupBy вместо Distinct:

context1.Transactions
    .GroupBy( x => 
       new { x.PersonID,
             x.TranDate,
             x.CreatedBy} )
     .Select( g=> g.First());
...