Comment copier et valider des données d'une table (toutes varchar) vers une autre (typées) en C #?

c# entity-framework sqlbulkcopy

Question

[note: doit être dans le code car ne peut pas utiliser SSIS ou similaire]

J'ai besoin de copier en bloc des données d'une base de données à une autre en utilisant C # et EF probablement - bien que cela ne soit pas immuable.

Le problème est que les données source sont toutes dans varchar (max) et que je veux que la destination soit dans les types de données corrects. La source est historique d'un vieil emploi ETL qui fonctionne très bien et je ne peux pas être remplacé. Le problème le plus courant que j'ai vu concerne les caractères alpha dans les champs numériques - par exemple, "aucun" dans un champ monétaire. Ce sont bien dans la source car tout est varchar.

J'aimerais copier les données et les valider:
source -> valider -> destination
de la manière la plus simple possible. Si la validation échoue, je dois connaître la ligne exacte qui a échoué (et idéalement WHAT) pour pouvoir la réparer manuellement dans la source et copier les données à nouveau.

Il y a environ 50 tables allant de 10 à 1,7 millions de lignes! Donc, la vitesse est également importante.

Quelle serait une façon sensée d’aborder cela? Créer des DTO, des attributs de validation et une carte automatique? Deux entités EF et mapper ligne par ligne et valider chacune? SPROC et insertion manuelle?

Réponse acceptée

Faites-le dans T-SQL avec un serveur lié .

C'est à dire:

--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

Si vous ne pouvez pas communiquer directement entre les serveurs, effectuez toujours la validation en SQL, mais utilisez un client C # pour écrire les données sur le disque et appuyez sur la fonction d'insertion en bloc sur le serveur de destination. Puisque le composant C # ne ferait que transporter les données, je voudrais simplement passer directement à un format utilisable par BULK INSERT , à la manière de CSV.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi