简体   繁体   English

用C#手动填充DataTable的最快方法

[英]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 . 为什么不使用DataTableLoadDataRow方法。

// 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM