使用DataTable.BeginLoadData优化DataSet.ReadXml后,EnforceConstraints异常为false的解决方法
解决DataSet多表加载后EnforceConstraints异常的问题
当使用BeginLoadData/EndLoadData配合ReadXml加载超大XML文件到包含多个DataTable的DataSet时,会出现最终dataSet.EnforceConstraints被设为false的问题——原因是每个DataTable的BeginLoadData会保存当前的约束状态并临时禁用约束:第一个表调用时保存原始的true状态并设为false,第二个表调用时保存的已经是false状态;执行EndLoadData时,第一个表恢复为true,第二个表又把它改回false,最终导致全局约束状态异常。
针对这个问题,有两种可靠的解决方式:
方案一:显式保存并恢复DataSet的约束状态
直接记录DataSet初始的EnforceConstraints状态,加载完成后手动恢复,不受单个DataTable的EndLoadData操作影响,逻辑清晰且可靠。
示例代码:
// 提前保存DataSet的原始约束状态 bool originalConstraintState = dataSet.EnforceConstraints; try { foreach (DataTable table in dataSet.Tables) { table.BeginLoadData(); } dataSet.ReadXml("file.xml"); } finally { foreach (DataTable table in dataSet.Tables) { table.EndLoadData(); } // 强制恢复到初始约束状态 dataSet.EnforceConstraints = originalConstraintState; }
方案二:调整EndLoadData的执行顺序
让第一个调用BeginLoadData的表最后执行EndLoadData,利用它保存的原始true状态来覆盖后续表的修改。需要注意的是,这种方式依赖于表的遍历顺序,若后续DataSet的表集合顺序发生变化,可能引发问题。
示例代码:
// 先把表存入列表固定顺序 List<DataTable> tableList = new List<DataTable>(dataSet.Tables); // 执行BeginLoadData foreach (DataTable table in tableList) { table.BeginLoadData(); } dataSet.ReadXml("file.xml"); // 反向遍历执行EndLoadData,先加载的表最后结束 for (int i = tableList.Count - 1; i >= 0; i--) { tableList[i].EndLoadData(); }
推荐方案
优先选择方案一,它不依赖于表的顺序,逻辑更直观,能确保DataSet的约束状态和加载前完全一致,避免潜在的顺序依赖风险。
内容的提问来源于stack exchange,提问作者exaiwitmx
相关产品推荐
相关产品推荐

