데이터 테이블에 대한 LINQ 쿼리
DataTable 개체에 대해 LINQ 쿼리를 수행하려고 하는데 이상하게도 DataTable에서 이러한 쿼리를 수행하는 것이 쉽지 않습니다.예:
var results = from myRow in myDataTable
where results.Field("RowNo") == 1
select results;
이것은 허용되지 않습니다.이와 같은 것을 어떻게 작동시킬 수 있습니까?
LINQ 쿼리가 데이터 테이블에서 허용되지 않는다는 것이 놀랍습니다!
다음에 대해 쿼리할 수 없습니다.DataTable
의 Rows 컬렉션, 이후DataRowCollection
하지 않습니다IEnumerable<T>
은 사을용합니다야를 해야 합니다.AsEnumerable()
의 내선 DataTable
이와 같은 경우:
var results = from myRow in myDataTable.AsEnumerable()
where myRow.Field<int>("RowNo") == 1
select myRow;
@Keith가 말했듯이 System에 대한 참조를 추가해야 합니다.데이터.데이터 세트 확장
AsEnumerable()
아온다를 합니다.IEnumerable<DataRow>
▁to▁need▁you▁▁if를 변환해야 하는 경우IEnumerable<DataRow>
DataTable
을 사용합니다.CopyToDataTable()
연장의
아래는 람다 식에 대한 쿼리입니다.
var result = myDataTable
.AsEnumerable()
.Where(myRow => myRow.Field<int>("RowNo") == 1);
var results = from DataRow myRow in myDataTable.Rows
where (int)myRow["RowNo"] == 1
select myRow
DataTables에서 의도적으로 허용되지 않은 것이 아니라, DataTables는 Linkq 쿼리를 수행할 수 있는 IQueryable 및 일반 IEnumberable 구조를 사전에 생성한 것입니다.
두 인터페이스 모두 몇 가지 정렬 유형 안전 검증이 필요합니다.데이터 테이블의 형식이 강력하지 않습니다.예를 들어, 이것은 사람들이 배열 목록에 대해 쿼리할 수 없는 이유는 다음과 같습니다.
Linkq가 작동하려면 결과를 유형 안전 개체에 매핑하고 대신 쿼리해야 합니다.
@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
를 또한다프추참합니다야가에 해야 합니다.System.Data.DataSetExtensions
저는 이에 대해 몇 번이나 답했다는 것을 알고 있지만, 다른 접근 방식을 제공하기 위해서입니다.
나는 그것을 사용하는 것을 좋아합니다..Cast<T>()
방법, 그것은 내가 명시적인 유형이 정의되고 깊이를 볼 때 제정신을 유지하는 데 도움이 된다고 생각합니다..AsEnumerable()
어쨌든 그것을 부릅니다.
var results = from myRow in myDataTable.Rows.Cast<DataRow>()
where myRow.Field<int>("RowNo") == 1 select myRow;
또는
var results = myDataTable.Rows.Cast<DataRow>()
.FirstOrDefault(x => x.Field<int>("RowNo") == 1);
처럼, 은 필요 .System.Data.DataSetExtensions
또는 기타 조립품(참고 자료)
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")
};
이름 및 기간 필드는 이제 쿼리 개체의 일부이며 콘솔과 같이 액세스할 수 있습니다.라인 쓰기(query.name );
LINQ를 사용하여 데이터 세트/데이터 테이블의 데이터 조작
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();
//
다음과 같은 간단한 쿼리 행을 사용해 보십시오.
var result=myDataTable.AsEnumerable().Where(myRow => myRow.Field<int>("RowNo") == 1);
LINQ를 사용하면 다음과 같이 행 집합의 개체에 사용할 수 있습니다.
var results = from myRow in myDataTable.Rows where myRow.Field("RowNo") == 1 select myRow;
람다 식을 사용하는 간단한 방법은 다음과 같습니다.
var results = myDataTable.Select("").FirstOrDefault(x => (int)x["RowNo"] == 1)
특정 값을 원하는 경우:
if(results != null)
var foo = results["ColName"].ToString()
사용해 보세요.
var row = (from result in dt.AsEnumerable().OrderBy( result => Guid.NewGuid()) select result).Take(3) ;
대부분의 경우 DataSet, DataTable 및 DataRow 클래스가 솔루션에 이미 정의되어 있습니다.그런 경우에는 DataSetExtensions 참조가 필요하지 않습니다.
예. DataSet 클래스 이름 -> CustomSet, DataRow 클래스 이름 -> CustomTableRow(정의된 열 포함:행 번호, ...
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);
var results = from myRow in myDataTable
where results.Field<Int32>("RowNo") == 1
select results;
애플리케이션에서 답변에 제시된 대로 DataTable에 대한 AsEnumerable() 확장자가 있는 데이터 세트에 LINQ를 사용하는 것은 매우 느립니다.속도 최적화에 관심이 있다면 James Newtonking의 Json을 사용하십시오.넷 라이브러리(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);
이를 달성하는 방법에 대한 예는 다음과 같습니다.
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();
VB.NET의 경우 코드는 다음과 같습니다.
Dim results = From myRow In myDataTable
Where myRow.Field(Of Int32)("RowNo") = 1 Select myRow
IEnumerable<string> result = from myRow in dataTableResult.AsEnumerable()
select myRow["server"].ToString() ;
해보세요...
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 );
}
다음과 같이 linq를 통해 우아하게 작업할 수 있습니다.
from prod in TenMostExpensiveProducts().Tables[0].AsEnumerable()
where prod.Field<decimal>("UnitPrice") > 62.500M
select prod
또는 dynamic linq와 마찬가지로 다음과 같습니다(AsDynamic은 DataSet에서 직접 호출됨).
TenMostExpensiveProducts().AsDynamic().Where (x => x.UnitPrice > 62.500M)
저는 가장 유연한 반면에 마지막 접근 방식을 선호합니다.추신: 연결하는 것을 잊지 마세요.System.Data.DataSetExtensions.dll
언급
시도할 수 있지만 각 열에 대한 값 유형을 확인해야 합니다.
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"),
});
저는 다음과 같은 해결책을 제안합니다.
DataView view = new DataView(myDataTable);
view.RowFilter = "RowNo = 1";
DataTable results = view.ToTable(true);
DataView 설명서에서 가장 먼저 확인할 수 있는 내용은 다음과 같습니다.
정렬, 필터링, 검색, 편집 및 탐색을 위한 데이터 테이블의 사용자 정의된 데이터 바인딩 가능 보기를 나타냅니다.
DataTable은 데이터만 저장하기 위한 것이며 DataView를 통해 DataTable에 대해 "쿼리"할 수 있습니다.
이 경우에는 다음과 같이 작동합니다.
SQL 문을 구현하려고 합니다.
SELECT *
FROM myDataTable
WHERE RowNo = 1
"데이터 테이블 언어"로 표시됩니다.C#에서는 다음과 같이 읽습니다.
FROM myDataTable
WHERE RowNo = 1
SELECT *
다음과 같이 C#으로 표시됩니다.
DataView view = new DataView(myDataTable); //FROM myDataTable
view.RowFilter = "RowNo = 1"; //WHERE RowNo = 1
DataTable results = view.ToTable(true); //SELECT *
언급URL : https://stackoverflow.com/questions/10855/linq-query-on-a-datatable
'programing' 카테고리의 다른 글
WPF 흐릿한 글꼴 문제 - 해결 방법 (0) | 2023.05.26 |
---|---|
Git 하위 모듈 추가: "git 디렉토리가 로컬로 검색됨" 문제 (0) | 2023.05.26 |
Xcode 4의 저작권 템플릿에서 회사 이름을 변경하려면 어떻게 해야 합니까? (0) | 2023.05.26 |
Xcode 편집기에서 라인 번호는 어디서 찾을 수 있습니까? (0) | 2023.05.26 |
Xcode가 충돌을 유발하는 라인을 표시하지 않음 (0) | 2023.05.26 |