我最近发现 Entity Framework 不再满足我将数据从一个数据库复制到另一个数据库的需求(它太慢了,我想提取比以前更多的数据)。所以我开始寻找替代品并找到了SqlBulkCopy
方法。问题是这SqlBulkCopy
不允许我“UPSERT”。再次,开始寻找解决方案并遇到了该DataTable.Merge(table)
功能。
根据我的研究,“最佳实践”似乎是使用 SqlBulkCopy 将我的数据导入“临时表”,然后使用DataTable.Merge()
然后以某种方式保存更改。保存更改是我遇到问题的部分。我有以下代码:
static void Main(string[] args)
{
using(var mdb = new meldbContext())
using(var odb = new ocmgccazTestEnvDbContext())
{
/*Is there a better way to clear the staging table that
doesn't require me to write actual SQL?*/
odb.Database.ExecuteSqlCommand("DELETE FROM almCallDetail_staging");
var lastUpdateTime = (from p in odb.almCallDetail
select p.time_of_contact).Max();
var query = from p in mdb.cl_contact_event
where p.time_of_contact >= lastUpdateTime
select new almCallDetail
{
id = p.id,
contact_list_name = p.contact_list_name,
account_number = p.account_number,
time_of_contact = p.time_of_contact
};
var conn = new SqlConnection(odb.Database.Connection.ConnectionString);
var bulkCopy = new SqlBulkCopy(conn)
{
BatchSize = 5000,
DestinationTableName = "almCallDetail_staging"
};
conn.Open();
bulkCopy.WriteToServer(query.ToDataTable());
var originalTable = (from p in odb.almCallDetail
where p.time_of_contact >= lastUpdateTime
select p).ToDataTable();
var stagingTable = (from p in odb.almCallDetail_staging
select p).ToDataTable();
/*Merge happens but the data is not actually saved to the almCallDetail
Table (originalTable)...*/
originalTable.Merge(stagingTable);
conn.Close();
}
}
如何更改它以保存合并操作的结果?
有没有更好的方法可以编写代码来实现快速导入/更新大量数据的目标?
进一步说明:我基本上只是从生产服务器的表中复制数据,以便(稍后)创建各种数据集,我可以将这些数据集转换为我们组的报告。我有一个计划任务,它将每 30 分钟左右运行一次此代码,以保持数据相对最新,我希望整个过程尽可能高效。IE 从生产服务器提取所需的最小数据量并将其复制到我的本地数据库。
我当前的实现完全基于实体框架。它:
- 从生产服务器中提取当天的数据集
- 循环遍历该组数据
- 将其与本地数据库进行比较
- 根据需要更新/添加
它完全符合我的需要,但速度非常慢(出于多种原因,我都理解)。因此,我渴望更新它。