c# - 将行添加到 DataTable
问题描述
如何通过从 csv 读取记录在没有 foreach 循环的情况下将行添加到数据表中?
var records = File.ReadLines(FD.FileName, Encoding.UTF8).Skip(1);
//not working because datatable is not thread safe
Parallel.ForEach(records, record => dataTable.Rows.Add(record.Split(',')));
//using for each is taking aroung 13 sec for 45000 records, need a better solution than this.
foreach (var record in records)
{
dataTable.Rows.Add(record.Split(','));
}
解决方案
我敢肯定,您不需要一次显示 50000 行。只是因为这不是人类可读的。
考虑分页:加载前 N 行,然后,当用户单击“下一页”按钮时,加载下 N 行,依此类推。
为数据行设置此类:
public class MyDataRow
{
public int Id { get; set; }
public string Name { get; set; }
}
分页演示将是这样的:
public partial class Form1 : Form
{
private const int PageSize = 10;
private readonly BindingList<MyDataRow> dataRows;
private readonly IEnumerator<string> csvLinesEnumerator;
public Form1()
{
InitializeComponent();
// start enumeration
csvLinesEnumerator = ReadLines().Skip(1).GetEnumerator();
// assign data source to DGV
dataRows = new BindingList<MyDataRow>();
dataGridView1.DataSource = dataRows;
// fetch first page
FetchNextPage();
}
private void button1_Click(object sender, EventArgs e) => FetchNextPage();
private void FetchNextPage()
{
// disable notifications
dataRows.RaiseListChangedEvents = false;
try
{
dataRows.Clear();
while (dataRows.Count < PageSize)
{
if (csvLinesEnumerator.MoveNext())
{
// parse next line and make row object from line's data
var lineItems = csvLinesEnumerator.Current.Split(',');
var row = new MyDataRow
{
Id = int.Parse(lineItems[0]),
Name = lineItems[1]
};
// add next row to the page
dataRows.Add(row);
}
else
{
break;
}
}
}
finally
{
// enable notifications and reload data source into DGV
dataRows.RaiseListChangedEvents = true;
dataRows.ResetBindings();
}
}
/// <summary>
/// This is just File.ReadLines replacement for testing purposes
/// </summary>
private IEnumerable<string> ReadLines()
{
for (var i = 0; i < 50001; i++)
{
yield return $"{i},{Guid.NewGuid()}";
}
}
}
用户界面:
另一种选择是使用DataGridView.VirtualMode
,但它主要针对情况进行了优化,当您知道总行数时(例如,您可以通过 SQL 查询计算它们),这对于 CSV 文件不适用。
推荐阅读
- amazon-web-services - 如何排除某些 AWS S3 存储桶文件
- http-status-codes - 语言过滤器失败的适当响应标头是什么?
- html - CSS在大于屏幕的元素之前居中
- java - 获得 otp 后,我想重定向以验证 otp 页面
- python - python:记录分数/用户并显示前10名
- artificial-intelligence - Dialogflow 列表第一次在 Google 助理上不起作用
- mysql - 在聚合视图的 WHERE 子句中建议动态日期的解决方法
- python - python脚本中的shell脚本,参数为sql脚本
- python - 列表python的元素明智合并
- typescript - get `keyof` non-optional property names in typescript