我使用Entity Framework 6和MySQL,尝试将数据从“生产”数据库表归档到“归档”数据库。我为每个数据库创建了两个DBContext。每个数据库都有相同的架构。
我可以使用以下代码将整个数据表从生产数据库移动到存档数据库:
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”中删除跟踪
答案 0 :(得分:0)
您是否尝试过在检索数据后处置第一个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();
}
答案 1 :(得分:0)
使用EF管理归档数据并不理想,对于低至中等的数据量或可分离的分区(即3-6个月的分区大小),使用insert-select + delete可以在数据库级别更好地实现类似目的可以在数据库之间移动。
要使用EF(仅建议用于小型和非复杂域模型)执行此操作,您应该能够通过在读取上下文中禁用代理生成,加载数据AsNoTracking
,然后将其添加到新的上下文DbSet。此示例不处理关联的实体,也不执行从产品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();
}
}