Entity Framework (MySQL) - перемещать данные из одной базы данных в другую, используя два dbcontexts - PullRequest
0 голосов
/ 04 июля 2018

Используя Entity Framework 6 и MySQL, я пытаюсь архивировать данные из рабочей таблицы базы данных в архивную базу данных. Я создал два DBContexts по одному для каждой базы данных. Каждая база данных имеет одинаковую схему.

Я могу переместить всю таблицу данных из рабочей базы данных в архивную базу данных, используя следующий код:

using (MyDBContext archiveContext = 
MyDBContext.CreateEntitiesForSpecificDatabaseName("archive_db"))
using (MyDBContext prodContext = 
MyDBContext.CreateEntitiesForSpecificDatabaseName("prod_db"))
{
    if(prodContext.myTable.Any())
    {
        archiveContext.myTable.AddRange(prodContext.myTable.AsNoTracking());
        archiveContext.SaveChanges();
    }  
}

Однако я не хочу архивировать всю таблицу, я хочу только архивировать данные старше определенной даты, поэтому я попробовал следующее:

using (MyDBContext archiveContext = 
MyDBContext.CreateEntitiesForSpecificDatabaseName("archive_db"))
using (MyDBContext prodContext = 
MyDBContext.CreateEntitiesForSpecificDatabaseName("prod_db"))
{
    IQueryable<myTable> dataToArchive =
      from mt in prodContext.myTable
      where mt.date < DateTimeSixMonths
      select mt;

     archiveContext.myTable.AddRange(dataToArchive);
     archiveContext.SaveChanges();
}       

но я не могу обойти исключение, которое я получаю при запуске этого:

System.InvalidOperationException: «Объект сущности не может быть ссылается на несколько экземпляров IEntityChangeTracker. '

Это происходит по этой строке:

archiveContext.myTable.AddRange(dataToArchive); 

Возможно ли как-то удалить отслеживание из dataToArchive

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Использование EF для управления архивированием данных не является идеальным, что-то вроде этого было бы лучше обслуживать на уровне базы данных, используя insert-select + delete для томов данных низкого или среднего размера или отсоединяемых разделов (т. Е. 3–6 мес. Размеров разделов) которые можно перемещать между базами данных.

Чтобы сделать это с EF (рекомендуется только для моделей небольших и несложных доменов), вы должны сделать это, отключив генерацию прокси в вашем контексте чтения, загрузить данные AsNoTracking, а затем добавить их в новый контекст DbSet. В этом примере не обрабатываются связанные сущности и не выполняется удаление из prod DbSet.

using (MyDBContext prodContext = 
        MyDBContext.CreateEntitiesForSpecificDatabaseName("prod_db"))
{
    prodContext.Configuration.ProxyCreationEnabled = false;
    dataToArchive = prodContext.myTable.AsNoTracking()
        .Where(mt => mt.Date < DateTimeSixMonths);


    using (MyDBContext archiveContext = 
        MyDBContext.CreateEntitiesForSpecificDatabaseName("archive_db"))
    {
        archiveContext.myTable.AddRange(dataToArchive);
        archiveContext.SaveChanges();
    }
}
0 голосов
/ 04 июля 2018

Вы пытались утилизировать первый DataContext после извлечения данных? Примерно так:

List<myTable> dataToArchive;

using (MyDBContext prodContext = 
        MyDBContext.CreateEntitiesForSpecificDatabaseName("prod_db"))
{

    dataToArchive = (from mt in prodContext.myTable
        where mt.date < DateTimeSixMonths
        select mt).ToList();
}

using (MyDBContext archiveContext = 
    MyDBContext.CreateEntitiesForSpecificDatabaseName("archive_db"))
{
    archiveContext.myTable.AddRange(dataToArchive);
    archiveContext.SaveChanges();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...