[英]Fastest way to fill DataTable manually in C#
I want to know if someone of you know a faster way to fill a DataTable manually then I do. 我想知道你们中是否有人知道一种更快的手动填充数据表的方法,然后我就知道了。
Here is what I got, I have a List with about 1.7b entries. 这是我得到的,我有一个包含1.7b条目的列表。 I want to fill this entries as fast as possible into DataTable with one column.
我想用一列尽快将这些条目填充到DataTable中。 An entry in my list looks like this here
{"A2C","DDF","ER","SQ","8G"}
我的列表中的条目如下所示:
{"A2C","DDF","ER","SQ","8G"}
My code need about 7-8 seconds 我的代码大约需要7-8秒
for (int i = 0; i <= lists.Count; i++)
{
table_list.Rows.Add();
}
for (int a = 0; a < list.Count; a++)
{
table_list.Rows[a][0] = list[a][0] + list[a][1] +
list[a][2] + list[a][3] + list[a][4];
}
As I didn't find any similar question on the board (just questions about how to fill datatable by sql and fill method), I decided to post my question. 由于我在板上没有发现任何类似的问题(只是有关如何通过sql和fill方法填充数据表的问题),所以我决定发布我的问题。
Any input is highly appreciated! 任何输入都非常感谢!
Why do you create an empty row first, then loop the table again to fill them? 为什么先创建一个空行,然后再次循环表以填充它们?
I would use a simple foreach
: 我将使用一个简单的
foreach
:
var table_list = new DataTable();
table_list.Columns.Add();
foreach(string[] fields in lists)
{
DataRow newRow = table_list.Rows.Add();
newRow.SetField(0, string.Join("", fields));
}
Why do you put all into one field? 你为什么要全都放在一个领域?
i add this DataTable into an sql server database (i do this by SqlBulkCopy)
我将此数据表添加到sql服务器数据库中(我通过SqlBulkCopy执行此操作)
This is a mistake; 这是个错误; the
DataTable
is pure overhead here. DataTable
在这里是纯开销。 What you should expose is an IDataReader
over that data. 您应该公开的是对该数据的
IDataReader
。 This API is a bit tricky, but FastMember makes it easier. 这个API有点棘手,但是FastMember使它更容易。 For example, it sounds like you have 1 column;
例如,听起来您有1列; so consider:
因此请考虑:
class Foo {
public string ColumnName {get;set;}
}
Now write an iterator block method that converts this from the original list per item: 现在编写一个迭代器块方法,将其从每个项目的原始列表转换为该方法:
IEnumerable<Foo> Convert(List<TheOldType> list) {
foreach(var row in list) {
yield return new Foo { ColumnName = /* TODO */ };
}
}
and now create an IDataReader
via FastMember on top of that lazy sequence: 然后在该惰性序列的顶部通过FastMember创建一个
IDataReader
:
List<TheOldType> list
var data = Convert(list);
using(var bcp = new SqlBulkCopy(connection))
using(var reader = ObjectReader.Create(data, "ColumnName"))
{
bcp.DestinationTableName = "SomeTable";
bcp.WriteToServer(reader);
}
This works much better than populating a DataTable
- in particular, it avoids populating a huge DataTable
. 这比填充
DataTable
更好,特别是避免填充巨大的DataTable
。 Emphasis: the above is spooling - not buffered. 重点:以上是假脱机 -未缓冲。
Why not use the LoadDataRow
method of the DataTable
. 为什么不使用
DataTable
的LoadDataRow
方法。
// turnoff notifications
table_list.BeginLoadData();
// load each row into the table
foreach(string[] fields in lists)
table_list.LoadDataRow(new object[] { string.Join("", fields) }, false);
// turn notifications back on
table_list.EndLoadData();
Also see: DataTable.LoadDataRow Method http://msdn.microsoft.com/en-us/library/kcy03ww2(v=vs.110).aspx 另请参阅: DataTable.LoadDataRow方法 http://msdn.microsoft.com/zh-cn/library/kcy03ww2(v=vs.110).aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.