zoukankan      html  css  js  c++  java
  • LINQ query on a DataTable

    LINQ query on a DataTable

    I'm trying to perform a LINQ query on a DataTable object and bizarrely I am finding that performing such queries on DataTables is not straightforward. For example:

    var results = from myRow in myDataTable
    where results.Field("RowNo") == 1
    select results;
    

    This is not allowed. How do I get something like this working?

    I'm amazed that LINQ queries are not allowed on DataTables!

    回答1

    You can't query against the DataTable's Rows collection, since DataRowCollection doesn't implement IEnumerable<T>. You need to use the AsEnumerable() extension for DataTable. Like so:

    var results = from myRow in myDataTable.AsEnumerable()
    where myRow.Field<int>("RowNo") == 1
    select myRow;
    

    And as @Keith says, you'll need to add a reference to System.Data.DataSetExtensions

    AsEnumerable() returns IEnumerable<DataRow>. If you need to convert IEnumerable<DataRow> to a DataTable, use the CopyToDataTable() extension.

    Below is query with Lambda Expression,

    var result = myDataTable
        .AsEnumerable()
        .Where(myRow => myRow.Field<int>("RowNo") == 1);
    

    回答2

    It's not that they were deliberately not allowed on DataTables, it's just that DataTables pre-date the IQueryable and generic IEnumerable constructs on which Linq queries can be performed.

    Both interfaces require some sort type-safety validation. DataTables are not strongly typed. This is the same reason why people can't query against an ArrayList, for example.

    For Linq to work you need to map your results against type-safe objects and query against that instead.

    回答3

    I realize this has been answered a few times over, but just to offer another approach:

    I like to use the .Cast<T>() method, it helps me maintain sanity in seeing the explicit type defined and deep down I think .AsEnumerable() calls it anyways:

    var results = from myRow in myDataTable.Rows.Cast<DataRow>() 
                      where myRow.Field<int>("RowNo") == 1 select myRow;
    

    or

    var results = myDataTable.Rows.Cast<DataRow>()
                      .FirstOrDefault(x => x.Field<int>("RowNo") == 1);
    

    As noted in comments, does not require System.Data.DataSetExtensions or any other assemblies (Reference)

    How I can filter a dataTable with Linq to datatable?

    You are better of using DataTable.Select method, but if you have to use LINQ then you can try:

    DataTable selectedTable = tb.AsEnumerable()
                                .Where(r => r.Field<string>("Modul") == value)
                                .CopyToDataTable();
    

    This would create a new DataTable based on filtered values.

    If you use DataTable.Select

    string expression = "Modul =" + value;
    DataRow[] selectedRows = tb.Select(expression);
    

    LINQ to DataTable

    Reference the DataTableExtensions -

    http://msdn.microsoft.com/en-us/library/system.data.datatableextensions.asenumerable.aspx

    Then...

    var whatever = dTable.AsEnumerable();
    

    Then per the MSDN example...

    var productNames = from products in table.AsEnumerable() 
          select products.Field<string>("ProductName");
    

    Edit/update: Unfortunately I do not think there is a built in direct cast back to a DataTable with a different schema. You have to use a DataTable? I believe it... as it might be too much effort to refactor and test your code. Good luck and keep us posted as working with strongly-typed lists are much more fun.

  • 相关阅读:
    无刷电机控制学习笔记
    "程序宅男"从改善皮肤开始——不再长痘
    跨平台国际化测试——Switch本体测试
    自动驾驶技术了解
    互联网加班狗:零碎时间学英语的方法
    ASCII,Unicode,GBK和UTF-8字符编码的区别和联系
    领域驱动设计的必要性和模型标准——《领域驱动设计-精简版》
    异步、非阻塞和IO多路复用总结
    Debian 8 安装Nginx最新版本
    字节、字、bit、Byte、byte的关系区分
  • 原文地址:https://www.cnblogs.com/chucklu/p/15329019.html
Copyright © 2011-2022 走看看