c# - example - Consulta LINQ en un DataTable
linq to datatable c# example (21)
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 debe agregar una referencia de proyecto a System.Data.DataSetExtensions
Estoy tratando de realizar una consulta LINQ en un objeto DataTable y, de manera extraña, 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 consigo que algo como esto funcione?
Me sorprende que las consultas LINQ no estén permitidas en DataTables.
Ejemplo de cómo lograr esto a continuación:
DataSet dataSet = new DataSet(); //Create a dataset
dataSet = _DataEntryDataLayer.ReadResults(); //Call to the dataLayer to return the data
//LINQ query on a DataTable
var dataList = dataSet.Tables["DataTable"]
.AsEnumerable()
.Select(i => new
{
ID = i["ID"],
Name = i["Name"]
}).ToList();
En mi aplicación, descubrí que el uso de LINQ to Datasets con la extensión AsEnumerable () para DataTable como se sugiere en la respuesta fue 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 )
// Serialize the DataTable to a json string
string serializedTable = JsonConvert.SerializeObject(myDataTable);
Jarray dataRows = Jarray.Parse(serializedTable);
// Run the LINQ query
List<JToken> results = (from row in dataRows
where (int) row["ans_key"] == 42
select row).ToList();
// If you need the results to be in a DataTable
string jsonResults = JsonConvert.SerializeObject(results);
DataTable resultsTable = JsonConvert.DeserializeObject<DataTable>(jsonResults);
Esta es una forma simple que funciona para mí y usa expresiones lambda:
var results = myDataTable.Select("").FirstOrDefault(x => (int)x["RowNo"] == 1)
Entonces si quieres un valor particular:
if(results != null)
var foo = results["ColName"].ToString()
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, ...)
var result = from myRow in myDataTable.Rows.OfType<CustomSet.CustomTableRow>()
where myRow.RowNo == 1
select myRow;
O (como yo prefiera)
var result = myDataTable.Rows.OfType<CustomSet.CustomTableRow>().Where(myRow => myRow.RowNo);
Me doy cuenta de que esto se ha respondido varias veces, pero solo para ofrecer otro enfoque, me gusta usar el .Cast<T>()
, me ayuda a mantener la cordura al ver el tipo explícito definido, y creo que en el fondo .AsEnumerable()
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);
No es que no se permitieran deliberadamente en las Tablas de datos, sino que las Tablas de datos son anteriores a las construcciones de IEnumerable IQueryable y genéricas en las que se pueden realizar las consultas de Linq.
Ambas interfaces requieren algún tipo de validación de seguridad de tipo. Las tablas de datos no están tipificadas fuertemente. Esta es la misma razón por la que las personas no pueden consultar contra un ArrayList, por ejemplo.
Para que Linq funcione, necesita mapear sus resultados contra objetos de tipo seguro y consultarlos en su lugar.
No puede consultar en la colección Rows del DataTable
, ya que DataRowCollection
no implementa IEnumerable<T>
. AsEnumerable()
usar la extensión AsEnumerable()
para DataTable
. Al igual que:
var results = from myRow in myDataTable.AsEnumerable()
where myRow.Field<int>("RowNo") == 1
select myRow;
Y como dice Keith, deberás agregar una referencia a System.Data.DataSetExtensions
AsEnumerable()
devuelve IEnumerable<DataRow>
. Si necesita convertir IEnumerable<DataRow>
a DataTable
, use la extensión CopyToDataTable()
.
Para VB.NET El código se verá así:
Dim results = From myRow In myDataTable
Where myRow.Field(Of Int32)("RowNo") = 1 Select myRow
Prueba esta simple línea de consulta:
var result=myDataTable.AsEnumerable().Where(myRow => myRow.Field<int>("RowNo") == 1);
Prueba esto
var row = (from result in dt.AsEnumerable().OrderBy( result => Guid.NewGuid()) select result).Take(3) ;
Prueba esto...
SqlCommand cmd = new SqlCommand( "Select * from Employee",con);
SqlDataReader dr = cmd.ExecuteReader( );
DataTable dt = new DataTable( "Employee" );
dt.Load( dr );
var Data = dt.AsEnumerable( );
var names = from emp in Data select emp.Field<String>( dt.Columns[1] );
foreach( var name in names )
{
Console.WriteLine( name );
}
Puedes hacerlo trabajar de forma elegante a través de linq así:
from prod in TenMostExpensiveProducts().Tables[0].AsEnumerable()
where prod.Field<decimal>("UnitPrice") > 62.500M
select prod
O como el linq dinámico esto (AsDynamic se llama directamente en DataSet):
TenMostExpensiveProducts().AsDynamic().Where (x => x.UnitPrice > 62.500M)
Yo prefiero el último enfoque mientras es el más flexible. PS: No olvide conectar la referencia System.Data.DataSetExtensions.dll
Puedes usar LINQ para objetos en la colección Rows, así:
var results = from myRow in myDataTable.Rows where myRow.Field("RowNo") == 1 select myRow;
puede intentar esto, pero debe estar seguro del tipo de valores para cada columna
List<MyClass> result = myDataTable.AsEnumerable().Select(x=> new MyClass(){
Property1 = (string)x.Field<string>("ColumnName1"),
Property2 = (int)x.Field<int>("ColumnName2"),
Property3 = (bool)x.Field<bool>("ColumnName3"),
});
Usando 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();
//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();
//
IEnumerable<string> result = from myRow in dataTableResult.AsEnumerable()
select myRow["server"].ToString() ;
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")
};
var results = from DataRow myRow in myDataTable.Rows
where (int)myRow["RowNo"] == 1
select myRow
var results = from myRow in myDataTable
where results.Field<Int32>("RowNo") == 1
select results;