LINQ-запрос к DataTable - PullRequest
       156

LINQ-запрос к DataTable

959 голосов
/ 14 августа 2008

Я пытаюсь выполнить запрос LINQ к объекту DataTable, и странным образом обнаруживаю, что выполнение таких запросов к объектам DataTable не является простым. Например:

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

Это не разрешено. Как мне заставить что-то подобное работать?

Я поражен, что запросы LINQ не разрешены в DataTables!

Ответы [ 21 ]

11 голосов
/ 18 мая 2012

Попробуйте это

var row = (from result in dt.AsEnumerable().OrderBy( result => Guid.NewGuid()) select result).Take(3) ; 
11 голосов
/ 24 апреля 2013

Скорее всего, классы для DataSet, DataTable и DataRow уже определены в решении. В этом случае вам не понадобится ссылка на DataSetExtensions.

Ex. Имя класса DataSet-> CustomSet, имя класса DataRow-> CustomTableRow (с определенными столбцами: RowNo, ...)

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

Или (как я предпочитаю)

var result = myDataTable.Rows.OfType<CustomSet.CustomTableRow>().Where(myRow => myRow.RowNo);
11 голосов
/ 19 марта 2015

Это простой способ, который работает для меня и использует лямбда-выражения:

var results = myDataTable.Select("").FirstOrDefault(x => (int)x["RowNo"] == 1)

Тогда, если вы хотите конкретное значение:

if(results != null) 
    var foo = results["ColName"].ToString()
9 голосов
/ 01 февраля 2014
var results = from myRow in myDataTable
where results.Field<Int32>("RowNo") == 1
select results;
7 голосов
/ 25 октября 2017

Пример того, как этого добиться, приведен ниже:

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();
7 голосов
/ 14 октября 2014

В моем приложении я обнаружил, что использование LINQ to Datasets с расширением AsEnumerable () для DataTable, как было предложено в ответе, было чрезвычайно медленным. Если вы заинтересованы в оптимизации скорости, используйте библиотеку Джеймса Ньютонкинга Json.Net (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);
6 голосов
/ 17 октября 2012

Для VB.NET код будет выглядеть так:

Dim results = From myRow In myDataTable  
Where myRow.Field(Of Int32)("RowNo") = 1 Select myRow
6 голосов
/ 04 августа 2015
IEnumerable<string> result = from myRow in dataTableResult.AsEnumerable()
                             select myRow["server"].ToString() ;
6 голосов
/ 10 апреля 2014

Попробуйте это ...

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 );
}
5 голосов
/ 02 февраля 2018

вы можете попробовать это, но вы должны быть уверены, что тип значений для каждого столбца

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"),    
});
...