3

我最近发现 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 从生产服务器提取所需的最小数据量并将其复制到我的本地数据库。

我当前的实现完全基于实体框架。它:

  1. 从生产服务器中提取当天的数据集
  2. 循环遍历该组数据
  3. 将其与本地数据库进行比较
  4. 根据需要更新/添加

它完全符合我的需要,但速度非常慢(出于多种原因,我都理解)。因此,我渴望更新它。

4

1 回答 1

4

可能这里最快的方法(如果不使用 SSIS)将使用带有MERGE语句的存储过程。
在存储过程中添加链接服务器。像这样的东西应该工作:

exec sp_addlinkedserver @server = 'ProductionServer'

MERGE [LocalServer].dbName.dbo.TableName AS Target
USING (SELECT * FROM [ProductionServer].dbName.dbo.TableName) AS source
ON TARGET.Id = source.Id
WHEN MATCHED
THEN UPDATE 
SET Field1 = source.Field1, Field2 = source.Field2, ---etc....
WHEN NOT MATCHED BY TARGET THEN
INSERT (Field1, Field2, Field3) 
VALUES (Field1, Field2, Field3) ;

此外,如果您需要从其中一个表中删除所有内容,您可以 使用Delete from. 像这样:

TRUNCATE TABLE TableName;
于 2012-11-16T01:53:13.447 回答