简体   繁体   English

从数据表中过滤行

[英]Filtering rows from DataTable

I have a DataTable with 1000000 records.我有一个包含 1000000 条记录的数据DataTable I am filtering records from DataTable .我正在从DataTable过滤记录。 I have used various methods for filtering:我使用了多种过滤方法:

  • DataTable.Select()
  • Linq to DataTable Linq 到数据表
  • DataView.RowFilter

After filtering records, binding the resulting records (approx. 1000 records) to a ListBox.筛选记录后,将结果记录(约 1000 条记录)绑定到 ListBox。

The whole process is taking much time.整个过程要花很多时间。 I analyzed the code and found that filtering is taking much time.我分析了代码,发现过滤花费了很多时间。 The whole process should be done in milliseconds.整个过程应该在几毫秒内完成。 For each filtering I can't hit on server to fetch records.对于每次过滤,我都无法访问服务器来获取记录。

Please suggest.请建议。

//using dataTable
DataRow[] dr = dtData.Select("i_pernr=" + perno + "");
dr.CopyToDataTable(dtTemp,LoadOption.OverwriteChanges);

//using DataView
dtData.DefaultView.RowFilter = "i_pernr=" + perno ;
dtTemp = dtData.DefaultView.ToTable();

//Using Linq
IEnumerable<DataRow> query = from m in dtData.AsEnumerable()
                             where m["i_pernr"] == perno
                             select m;
query.CopyToDataTable(dtTemp,LoadOption.OverwriteChanges);

If you really feel that filtering at the source isn't possible (SQL Server is much better at selecting records) you can only speed up the selection operation by setting the PrimaryKey for the DataTable .如果您真的觉得无法在源头进行过滤(SQL Server 在选择记录方面要好得多),您只能通过为DataTable设置PrimaryKey来加快选择操作。

dtData.PrimaryKey = new DataColumn[] { dtData.Columns["i_pernr"]};

Notice that you can have multiple columns as primarykey columns.请注意,您可以将多个列作为主键列。 You'll have to add as much as needed to make guarantee the datarows you add/have are unique.您必须根据需要添加尽可能多的内容,以确保您添加/拥有的数据行是唯一的。

I've used the following test rig:我使用了以下测试装置:

var dtTemp = new DataTable();
dtTemp.Columns.Add("i_pernr", typeof(int));
dtTemp.Columns.Add("name", typeof(string));

var dtData = new DataTable();
dtData.Columns.Add("i_pernr", typeof(int));
dtData.Columns.Add("name", typeof(string));
dtData.PrimaryKey = new DataColumn[] { 
    dtData.Columns["i_pernr"], 
    dtData.Columns["name"]
    };

var rnd = new Random();
for(int r = 1; r<1000000; r++)
{
    var row =dtData.NewRow();
    row[0] = rnd.Next(1000);
    row[1]= String.Format("the lazy fox jumps again {0}",rnd.Next(10000000)) ;
    try
    {
       dtData.Rows.Add(row);
    }
    catch
    {
       // Hey, for testing this is fine ...
    }
}

This loads a datatable with enough rows to test the effect of having or not having a PrimaryKey it the stopwatch:这会加载一个包含足够行的数据表,以测试秒表是否具有 PrimaryKey 的效果:

dtData.Rows.Count.Dump("rows");

var perno = rnd.Next(1000).ToString();

var sw = new Stopwatch();
sw.Start();
DataRow[] dr = dtData.Select("i_pernr=" + perno + "");
dr.CopyToDataTable(dtTemp,LoadOption.OverwriteChanges);
sw.Stop();
sw.ElapsedMilliseconds.Dump("elapsed");
sw.ElapsedTicks.Dump("ticks");

This output in LinqPad when using the PrimaryKey:使用 PrimaryKey 时 LinqPad 中的此输出:

elapsed:    0 
ticks:  5,371

Without the primarykey the results are:没有主键,结果是:

elapsed:     2,444 
ticks:   7,541,415 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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