如何在C#中将数据从一个表(所有varchar)复制并验证到另一个(typed)?

时间:2013-02-27 05:11:44

标签: c# entity-framework sqlbulkcopy

[注意:需要在代码中,因为不能使用SSIS或类似的东西]

我需要使用C#和EF将数据从一个数据库批量复制到另一个数据库 - 尽管这不是一成不变的。

问题是源数据全部在varchar(max)中,我希望目标在正确的数据类型中。来源是旧的ETL工作的历史,工作得非常好,我无法取代。我见过的最常见的问题是数字字段中的alpha - 例如金钱领域的“无”。这些在源代码中很好,因为它都是varchar。

我想复制数据并对其进行验证:
来源 - >验证 - >目的地
以最简单的方式。如果验证失败,那么我需要知道失败的确切行(理想情况下失败了),以便可以在源中手动修复它,并重新复制数据。

大约有50个表,行数在10到1.7M之间!所以速度也很重要。

什么是理智的方法来解决这个问题?创建DTO,验证属性和自动化?两个EF实体并逐行映射并验证每个实体? SPROC和手动插入?

1 个答案:

答案 0 :(得分:2)

使用linked server在T-SQL中执行此操作。

I.e。:

--begin a transaction to wrap validation and load
BEGIN TRAN

--Validate that no tickets are set to closed without a completion date
SELECT * 
FROM bigTableOnLocalServer with (TABLOCKX) -- prevent new rows
WHERE ticketState = '1' /* ticket closed */ and CompletionDate = 'open' 

--if validation fails, quit the transaction to release the lock
COMMIT TRAN

--if no rows in result set 1, execute the load
INSERT INTO RemoteServerName.RemoteServerDBName.RemoteSchema.RemoteTable (field1Int, Field2Money, field3text)
SELECT CAST(Field1 as int), 
    CASE Field2Money WHEN 'none' then null else CAST(Field2Money as money) END,
    Field3Text
FROM bigTableOnLocalServer
WHERE recordID between 1 and 1000000

-- after complete, commit the transaction to release the lock
COMMIT TRAN

如果无法在服务器之间直接通信,仍然在SQL中进行验证,但使用C#客户端将数据写入磁盘并点击目标服务器上的批量插入功能。由于C#组件只会传输数据,因此我会直接使用BULK INSERT可用的格式,即CSV格式。