我有一个DataTable
对象,我需要根据存储在列流中的数据来填充 - 即流最初包含DataTable的模式,然后是按列组织的值
目前,我采取了相当天真的方法
结果是每单元格迭代,至少可以说不是特别快。
那是:
// Create rows first...
// Then populate...
foreach (var col in table.Columns.Cast<DataColumn>)
{
List<object> values = GetValuesfromStream(theStream);
// Actual method has some DBNull checking here, but should
// be immaterial to any solution.
for (var i=0; i<values.Count; i++)
table.Rows[i][col] = values[i];
}
我的猜测是每个列的后备DataStorage
项目都没有随着行的添加而扩展,但是随着值被添加到每个列,但我还远未确定。有关加载此类数据的任何提示。
请注意,首先加载所有列表然后逐行读取可能不合理 - 首先要采用这种方法来减少序列化巨大DataTable
个对象时可能导致的内存异常,抓住整个数据网格的克隆并将其读入可能只会将问题转移到其他地方。对于原始表和另一列值,肯定有足够的内存,但可能没有DataTable
的两个副本。
答案 0 :(得分:1)
虽然我没有找到避免迭代单元格的方法,但根据上面的评论,我发现写入已添加到表格中的DataRow
项目的原因是这是一个坏主意,并且是我观察到的绝大部分减速的原因。
我使用的最终方法最终看起来像这样:
List<DataRow> rows = null;
// Start population...
var cols = table.Columns.Cast<DataColumn>.Where(c => string.IsNullOrEmpty(c.Expression));
foreach (var col in cols)
{
List<object> values = GetValuesfromStream(theStream);
// Create rows first if required.
if (rows == null)
{
rows = new List<DataRow>();
for (var i=0; i<values.Count; i++)
rows.Add(table.NewRow());
}
// Actual method has some DBNull checking here, but should
// be immaterial to any solution.
for (var i=0; i<values.Count; i++)
rows[i][col] = values[i];
}
rows.ForEach(r => table.Rows.Add(r));
这种方法解决了两个问题:
DataRow
添加到具有空限制或类似限制的表中,那么您将收到错误消息。这种方法确保所有数据在添加之前都存在,这应该可以解决大多数此类问题(尽管我还没有必要检查它如何与自动递增PK列一起使用)。由于我使用的表格没有使用DataTable
类/模型的那些功能,因此写入桌面时可能会出现其他并发症。但对于简单的情况,这很有效。