Estoy tratando de realizar una consulta LINQ en un objeto DataTable y extrañamente encuentro 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 hago para que algo así funcione?
¡Estoy sorprendido de que las consultas LINQ no estén permitidas en DataTables!
Respuestas:
No puede consultar la colección de filas de
DataTable
's , ya que no se implementa . Necesita usar la extensión para . Al igual que:DataRowCollection
IEnumerable<T>
AsEnumerable()
DataTable
Y como dice @Keith , deberá agregar una referencia a System.Data.DataSetExtensions
AsEnumerable()
vuelveIEnumerable<DataRow>
. Si necesita convertirIEnumerable<DataRow>
a aDataTable
, use laCopyToDataTable()
extensión.A continuación se muestra la consulta con la expresión Lambda,
fuente
using System.Data;
myDataTable.Rows
lugar como sugirió @JoelFan.myDataTable.Rows
es porque lamyRow
variable está explícitamente convertida enDataRow
. Cuando se compila, esa consulta se reescribe enmyDataTable.Rows.Cast<DataRow>().Where(myRow => (int)myRow["RowNo"] == 1)
. Personalmente, no encuentro la llamada aAsEnumerable()
más complicada que la llamada aCast<DataRow>()
. Hasta donde yo sé, el rendimiento es el mismo, por lo que es solo una cuestión de preferencia.fuente
(int)myRow["RowNo"]
con la forma genéricamyRow.Field<int>("RowNo")
para admitir más convenientemente los tipos anulables.No es que no se les haya permitido deliberadamente en DataTables, es solo que DataTables es anterior a las construcciones IQueryable y genéricas IEnumerable en las que se pueden realizar consultas Linq.
Ambas interfaces requieren algún tipo de validación de seguridad de tipo. Las tablas de datos no están fuertemente tipadas. Esta es la misma razón por la cual las personas no pueden consultar contra una ArrayList, por ejemplo.
Para que Linq funcione, necesita mapear sus resultados con objetos seguros para escribir y consultar en su lugar.
fuente
Como @ ch00k dijo:
También debe agregar una referencia de proyecto a
System.Data.DataSetExtensions
fuente
myRow
o usoCast<DataRow>()
sobreRows
. Mejor de usarAsEnumerable()
.System.Linq
ySystem.Data.DataSetExtensions
luegomyDataTable.Rows
devuelva una colección enumerable deDataRow
todos modos. Eso podría haber cambiado, ha pasado una década desde que lo usé.DataSet
extensiones no hayan llegado a .NET Core o .NET Standard, ya estaban desactualizadas cuando publiqué esta respuesta. Realmente no lo usaríaDataSet
en nuevos proyectos, hay modelos de acceso a datos mucho mejores, tanto para facilitar la codificación como para el rendimiento.DataRowCollection
no se implementaIEnumerable<T>
soloIEnumerable
y, por lo tanto, no funciona con LINQ fuertemente tipado.los campos de nombre y edad ahora son parte del objeto de consulta y se puede acceder de esta manera: Console.WriteLine (query.name);
fuente
MessageBox.Show(name)
no está definido.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 que lo.AsEnumerable()
llama de todos modos:o
Como se señaló en los comentarios, no se necesitan otros ensamblajes ya que es parte de Linq ( Referencia )
fuente
Usando LINQ para manipular datos en DataSet / DataTable
fuente
System.Data.DataSetExtensions
.fuente
Pruebe esta simple línea de consulta:
fuente
Puede usar LINQ para objetos en la colección Filas, de esta manera:
fuente
DataTable.Rows
no se implementaIEnumerable
, no puedo ver cómo se podría compilar esta consulta.Esta es una manera simple que funciona para mí y utiliza expresiones lambda:
Entonces, si quieres un valor particular:
fuente
Prueba esto
fuente
Lo más probable es que las clases para DataSet, DataTable y DataRow ya estén definidas en la solución. Si ese es el caso, no necesitará la referencia DataSetExtensions.
Ex. Nombre de clase DataSet-> CustomSet, nombre de clase DataRow-> CustomTableRow (con columnas definidas: RowNo, ...)
O (como prefiero)
fuente
fuente
En mi aplicación, descubrí que usar LINQ to Datasets con la extensión AsEnumerable () para DataTable, como se sugiere en la respuesta, era extremadamente lento. Si está interesado en optimizar la velocidad, use la biblioteca Json.Net de James Newtonking ( http://james.newtonking.com/json/help/index.html )
fuente
System.Data.DataRow
objetos pesados . La tabla de datos serializados y analizados crea datos livianos que consisten solo en los nombres y valores de columna de cada fila. Cuando se ejecuta la consulta, cargará los datos en la memoria, lo que para un gran conjunto de datos puede implicar el intercambio. A veces, la sobrecarga de varias operaciones es menor que la sobrecarga de copiar grandes cantidades de datos dentro y fuera de la memoria.Para VB.NET El código se verá así:
fuente
fuente
Ejemplo sobre cómo lograr esto se proporciona a continuación:
fuente
Prueba esto...
fuente
Puede hacerlo funcionar elegante a través de linq de esta manera:
O como dynamic linq this (AsDynamic se llama directamente en DataSet):
Prefiero el último enfoque, mientras que es el más flexible. PD: no olvides conectar la
System.Data.DataSetExtensions.dll
referenciafuente
puede intentar esto, pero debe estar seguro del tipo de valores para cada columna
fuente
Propongo la siguiente solución:
Mirando la documentación de DataView , lo primero que podemos ver es esto:
Lo que obtengo de esto es que DataTable está destinado a almacenar solo datos y DataView está allí nos permite "consultar" contra DataTable.
Así es como funciona esto en este caso particular:
Intenta implementar la instrucción SQL
en "lenguaje DataTable". En C # lo leeríamos así:
que se ve en C # así:
fuente
fuente