Pregunta Consulta LINQ en una DataTable


Intento realizar una consulta LINQ en un objeto DataTable y, curiosamente, me parece que realizar tales consultas en DataTables no es sencillo. Por ejemplo:

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

Esto no esta permitido. ¿Cómo puedo hacer que algo como esto funcione?

¡Me sorprende que las consultas de LINQ no estén permitidas en DataTables!


883
2017-08-14 10:08


origen


Respuestas:


No puedes consultar contra el DataTablees Filas colección, desde DataRowCollection no implementa IEnumerable<T>. Necesitas usar el AsEnumerable() extensión para DataTable. Al igual que:

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

Y como dice Keith, necesitarás agregar una referencia a System.Data.DataSetExtensions

AsEnumerable() devoluciones IEnumerable<DataRow>. Si necesitas convertir IEnumerable<DataRow> a un DataTable, utilizar el CopyToDataTable() extensión.


1120
2017-08-14 19:45



var results = from DataRow myRow in myDataTable.Rows
    where (int)myRow["RowNo"] == 1
    select myRow

111
2018-03-05 02:53



No es que no se les permitiera deliberadamente en DataTables, es solo que DataTables es anterior a las construcciones IQueryable y genéricas de IEnumerable en las que se pueden realizar consultas de Linq.

Ambas interfaces requieren algún tipo de validación de seguridad de tipo. Los DataTables no están fuertemente tipados. Esta es la misma razón por la cual las personas no pueden consultar contra una ArrayList, por ejemplo.

Para que Linq funcione, debe asignar sus resultados a objetos de tipo seguro y consultar en su lugar.


57
2017-08-14 10:10



Como dijo @ ch00k:

using System.Data; //needed for the extension methods to work

...

var results = 
    from myRow in myDataTable.Rows 
    where myRow.Field<int>("RowNo") == 1 
    select myRow; //select the thing you want, not the collection

También necesita agregar una referencia de proyecto a System.Data.DataSetExtensions


45
2017-08-14 11:07



var query = from p in dt.AsEnumerable()
                    where p.Field<string>("code") == this.txtCat.Text
                    select new
                    {
                        name = p.Field<string>("name"),
                        age= p.Field<int>("age")                         
                    };

33
2018-05-23 04:03



Usar LINQ para manipular datos en DataSet / DataTable

var results = from myRow in tblCurrentStock.AsEnumerable()
              where myRow.Field<string>("item_name").ToUpper().StartsWith(tbSearchItem.Text.ToUpper())
              select myRow;
DataView view = results.AsDataView();

24
2017-07-13 11:21



//Create DataTable 
DataTable dt= new DataTable();
dt.Columns.AddRange(New DataColumn[]
{
   new DataColumn("ID",typeOf(System.Int32)),
   new DataColumn("Name",typeOf(System.String))

});

//Fill with data

dt.Rows.Add(new Object[]{1,"Test1"});
dt.Rows.Add(new Object[]{2,"Test2"});

//Now  Query DataTable with linq
//To work with linq it should required our source implement IEnumerable interface.
//But DataTable not Implement IEnumerable interface
//So we call DataTable Extension method  i.e AsEnumerable() this will return EnumerableRowCollection<DataRow>


// Now Query DataTable to find Row whoes ID=1

DataRow drow = dt.AsEnumerable().Where(p=>p.Field<Int32>(0)==1).FirstOrDefault();
 // 

24
2018-01-05 08:43



Me doy cuenta de que esto ha sido respondido varias veces, pero solo para ofrecer otro enfoque, me gusta usar el .Cast<T>() método, me ayuda a mantener la cordura al ver el tipo explícito definido, y en el fondo creo .AsEnumerable() lo llama de todos modos:

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

o

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

19
2018-02-02 21:22