C#快速上传相关表格

时间:2018-02-19 14:42:16

标签: c# sql sql-server

我正在研究动态加载程序。基于定义平面文本文件的数据库表,我可以读取具有多种记录类型的单个文件,并将其加载到数据库表中。这些表是相关的并使用身份主键。一切都在工作,但运行速度非常慢,因为它都是由单个插入语句完成的。我正在努力优化流程,无法找到一个简单的方法。或者'最佳实践'在网上回答。

我目前的项目涉及8个表格,但为了简化,我将使用客户/订单示例。

让我们看看下面的两个客户,数据将重复每组客户和数据文件中的订单。父记录总是在子记录之前。第一个字段是记录类型,每个记录类型对后面的字段有不同的定义。这都是在控制表中指定的。

CUST|Joe Green|123 Main St
ORD|Pancakes|5
ORD|Nails|2
CUST|John Deere|456 Park Pl
ORD|Tires|4

当前代码:

  • 插入客户Joe Green并返回ID。 (使用输出 Inserted.Id在insert语句中)
  • 插入附加返回ID的煎饼和指甲。
  • 插入客户John Deere并返回ID。
  • 使用返回ID插入订单轮胎。

这种情况非常缓慢。如果这可以优化,我不会改变很多代码,那将是理想的,但我不能想到如何。

那么解决方案呢?我在想数据表......到目前为止,我正在思考这个问题。

  • 创建交易
  • 在这种情况下,锁定属于'文件定义的所有表格 客户和订单获取每个表的最大ID并按1递增 获得所有表的起始ID
  • 为所有表创建数据表
  • 执行当前设置但不发出插入语句 添加到数据表
  • 读取数据后,批量上传表格的顺序正确 关系
  • 解锁表格
  • 结束交易

我想知道,在我走这条路之前,如果有人找到了更好的解决方案。我也在考虑SSIS中的自定义脚本组件。我看过关于暂停提交交易的帖子和博客,但每个父记录只有少数子记录,树可以达到4深,想想订单详情和产品。由于需要父记录ID,我需要提交父记录的插入。我还考虑过自己管理ID,而不是身份,但如果可以避免,我不想添加额外的管理。

根据答案进行更新,以澄清/背景。

典型的文本文件有

one file header record
- 5 facility records that relate to the file header
- 7,000 customers(account)
- 5 - 10 notes per customer
- 1-5 payments at the account level
- 1-5 adjustments at the account level
- 5 - 20 orders per customer
- 5 - 20 order details per order
- 1-5 payments at the order level
- 1-5 adjustments at the order level
- one file trailer record related to the file header



Keys
- File Header -> Facility -> Customer (Account)
- File Header -> FileTrailer
- Customer -> Notes
- Customer -> Payments
- Customer -> Adjustments
- Customer -> Orders
- Order -> OrderDetails
- Order -> Payments
- Order -> Adjustments

还涉及更多的表格,但这应该让我们了解整体情况。

Data Sample ... = MORE FIELDS .... MORE RECORDS
HEADER|F1|F2|...
FACILITY|F1|F2|..
CUSTOMER|F1|F2|...
NOTE|F1|F2|....
....
ORDER|F1|F2|...
ORDERDETAIL|F1|F2|...
.... ORDER DETAILS
ORDERPYMT|F1|F2|...
....
ORDERADJ|F1|F2|...
....
CUSTOMERPYMT|F1|F2|...
....
CUSTOMERADJ|F1|F2|...
....

(The structure repeats for each facility)

TRAILER|F1|F2|...

1 个答案:

答案 0 :(得分:1)

插入具有低数据量的相关表通常不应该是一个问题。如果它们很慢,我们将需要更多背景来回答您的问题。

如果由于要插入许多记录而遇到问题,则可能需要查看SqlBulkCopy
如果您不想自己管理您的ID,我所知道的最简洁的方法是使用临时占位符ID列。

  • 使用您自己填写的数据和tempId列以及外键空白
  • 创建和填充数据表
  • SqlBulkCopy主表
  • 通过tempid列
  • 从以前插入的表中查找主键,用生成的外键更新辅助数据表
  • 上传辅助表格
  • 重复完成
  • 删除临时id列(可选)