最近我发现实体框架不再满足将数据从一个数据库复制到另一个数据库的需求(它实在太慢了,而且我还想拉动更多数据比我一直)。于是我开始研究替代方案,并找到了SqlBulkCopy
方法。问题是SqlBulkCopy
不允许我“UPSERT”。再次,开始寻找解决方案,并遇到了DataTable.Merge(table)
函数。实体框架的SqlBulkCopy(和更新)
根据我的研究,似乎“最佳做法”是使用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分钟左右运行一次该代码,以保持数据相对最新,并希望整个过程尽可能高效。 I.E.从生产服务器提取所需的最小数据量并将其复制到本地数据库。
我目前的实现完全是基于实体框架的。它:
- 拉当天的一组数据从生产服务器
- 循环通过一组数据
- 将它与本地数据库
- 更新/根据需要增加
它正是我所需要的,但它超级慢(出于几个原因,我理解了所有这些)。因此,我希望更新它。
为什么不使用像SSIS这样的ETL工具?这就是他们所设计的。 –
@DStanley我无法使用SSIS,因为我正在使用SQL Server Express。 – Kittoes0124
你有没有想过解决这个问题的解决方案? –