[c#] Query LINQ su un DataTable


Answers

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

Sto cercando di eseguire una query LINQ su un oggetto DataTable e in modo bizzarro sto trovando che l'esecuzione di tali query su DataTable non è semplice. Per esempio:

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

Questo non è permesso. Come faccio a ottenere qualcosa di simile a questo?

Sono sorpreso che le query LINQ non siano consentite su DataTable!




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



Prova questo...

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 );
}



Molto probabilmente, le classi per DataSet, DataTable e DataRow sono già definite nella soluzione. Se questo è il caso, non avrai bisogno del riferimento DataSetExtensions.

Ex. Nome classe DataSet-> CustomSet, Nome classe DataRow-> CustomTableRow (con colonne definite: RowNo, ...)

var result = from myRow in myDataTable.Rows.OfType<CustomSet.CustomTableRow>()
             where myRow.RowNo == 1
             select myRow;

O (come preferisco)

var result = myDataTable.Rows.OfType<CustomSet.CustomTableRow>().Where(myRow => myRow.RowNo);



Mi rendo conto che a questa domanda è stata data risposta alcune volte, ma solo per offrire un altro approccio, mi piace usare il .Cast<T>() , mi aiuta a mantenere la sanità mentale nel vedere definito il tipo esplicito, e in fondo penso .AsEnumerable() chiama comunque:

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);



Nella mia applicazione ho scoperto che l'utilizzo di LINQ to Dataset con l'estensione AsEnumerable () per DataTable come suggerito nella risposta era estremamente lento. Se ti interessa ottimizzare la velocità, usa la libreria Json.Net di 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);



Come @ ch00k ha detto:

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

È inoltre necessario aggiungere un riferimento al progetto a System.Data.DataSetExtensions




Prova questa semplice riga di query:

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






Esempio su come ottenere questo fornito di seguito:

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();



Related