標識列上具有父/子關係的SqlBulkCopy和DataTables

.net c# sqlbulkcopy sql-server

我們需要根據父表中的Identity主鍵更新多個具有父/子關係的表,父表由一個或多個子表作為外鍵引用。

  • 由於數據量很大,我們希望在內存中構建這些表,然後使用C#中的SqlBulkCopy從DataSet或單個DataTables更新數據庫。
  • 我們還希望從多個線程,進程和可能的客戶端並行執行此操作。

我們在F#中的原型顯示了很多承諾,性能提高了34倍,但是這段代碼強制了父表中已知的Identity值。如果沒有強制,當SqlBulkCopy插入行時,Identity列會在數據庫中正確生成,但Identity值不會在內存中的DataTable中更新。此外,即使它們是,也不清楚DataSet是否能正確地修復父/子關係,以便隨後可以用正確的外鍵值寫入子表。

任何人都可以解釋如何使用SqlBulkCopy更新標識值,以及如何配置數據集以保留和更新父/子關係,如果在單個DataTables上調用DataAdapter到FillSchema時不自動完成。

我不想要的答案:

  • 讀取數據庫以查找當前最高的Identity值,然後在創建每個父行時手動遞增它。不適用於多個進程/客戶端,據我所知,失敗的事務可能會導致某些標識值被跳過,因此這種方法可能會破壞關係。
  • 一次一個地寫出父行,並要求返回Identity值。通過使用SqlBulkCopy,這至少會破壞一些收益(是的,有多個子行比父類行多,但仍有很多父行)。

類似於以下未回答的問題:

熱門答案

首先:SqlBulkCopy不可能做你想要的。顧名思義,它只是一條“單行道”。我盡可能快地將數據移動到sql server中。它是舊的批量複製命令的.Net版本,它將原始文本文件導入表中。因此,如果使用SqlBulkCopy,則無法獲取標識值。

我做了很多批量數據處理,並且多次遇到過這個問題。解決方案取決於您的體系結構和數據分佈。以下是一些想法:

  • 為每個線程創建一組目標表,在這些表中導入。最後加入這些表格。其中大多數可以通過一種非常通用的方式實現,您可以從名為TABLENAME的表中自動生成名為TABLENAME_THREAD_ID的表。

  • 將ID生成完全移出數據庫。例如,實現生成ID的中央Web服務。在這種情況下,您不應該為每個調用生成一個ID,而是生成ID範圍。否則,網絡開銷通常會變成瓶頸。

  • 嘗試為您的數據生成ID。如果可能的話,你的問題就會消失。不要說快“是不可能的”。也許您可以使用可以在後處理步驟中清理的字符串ID?

還有一點評論:使用BulkCopy時,因子34的增加會增加。如果要快速插入數據,請確保正確配置數據庫。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow