我正在构建一个应用程序以将数据导入到 sql server 2008 Express 数据库中。
当前正在生产中的应用程序正在使用此数据库。
需要导入的数据来自各种来源,主要是excel表格和xml文件。
数据库有下表:
- 工具
- 动力工具
- 醒目的工具
- 所有者
源文件中的每一行或 xml 标记都有关于 1 个工具的信息:
名称、工具类型、重量、瓦数、所有者、 Material 等...
这些行中的每一行都有工具所有者的名称,必须将此名称插入到所有者表中,但前提是该名称尚不存在。
对于这些行中的每一行,都需要在工具表中插入一个新行。
tools表有一个字段owner_id,外键指向owners表,需要设置owners表中对应行的主键
根据工具类型,必须在 powertools 表或 strikingtools 表中创建一个新行。这 2 个表还有一个 tool_id 字段,其中包含必须填写的 tools 表的外键。
tools 表有一个 tool_owner_id 字段,其中包含必须填写的 owners 表的外键。
如果导入文件中的任何行由于某种原因导入失败,则需要回滚整个导入
目前我正在使用数据集来执行此操作,但对于一些大文件(超过 200.000 个工具),这需要大量内存。有人能为此想到更好的方法吗?
最佳答案
主要有两个问题需要解决:
- 有效地解析大型 XML 文档。
- 向数据库中添加大量记录。
XML 解析
虽然 DataSet 方法有效,但整个 XML 文档都被加载到内存中。要提高处理大型 XML 文档的效率,您可能需要查看 XmlReader类(class)。 API 比 DataSet 稍微难用一点提供。但是您将获得不将整个 DOM 立即加载到内存中的好处。
将记录插入数据库
满足您的Atomicity要求您可以使用单个数据库事务,但是您为单个事务处理的大量记录并不理想。您很可能会遇到以下问题:
- 数据库必须处理大量的锁
- 可能从行锁升级为页锁甚至表锁的数据库锁。
- 数据库的并发使用将在导入过程中受到严重影响。
我会推荐以下而不是单个数据库事务:
- 看看是否可以创建更小的交易批处理。一次可能有 100 条记录。或许可以在逻辑上将 XML 文件的各个部分一起加载,这样可以将数据的子集作为一个单元加载到系统中。
- 预先验证尽可能多的数据。例如。检查必填字段是否已填写或 FK 是否正确。
- 使上传可重复。跳过现有数据。
- 提供手动撤消策略。我知道这说起来容易做起来难,但甚至可能需要作为附加的业务规则。例如,上传成功,但几个小时后有人意识到上传了错误的文件。
将数据上传到数据库中的初始暂存区域以执行验证并标记已处理的记录可能很有用。
关于c# - 应用感知数据导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2381563/