Saya mencoba untuk melakukan query LINQ pada objek DataTable dan anehnya saya menemukan bahwa melakukan query seperti pada DataTable tidak mudah. Sebagai contoh:
var results = from myRow in myDataTable
where results.Field("RowNo") == 1
select results;
Ini tidak diizinkan Bagaimana saya membuat sesuatu seperti ini berfungsi?
Saya kagum bahwa kueri LINQ tidak diizinkan di DataTables!
Jawaban:
Anda tidak bisa query terhadap
DataTable
's Rows koleksi, karenaDataRowCollection
tidak melaksanakanIEnumerable<T>
. Anda perlu menggunakanAsEnumerable()
ekstensi untukDataTable
. Seperti itu:Dan seperti yang dikatakan @Keith , Anda perlu menambahkan referensi ke System.Data.DataSetExtensions
AsEnumerable()
kembaliIEnumerable<DataRow>
. Jika Anda perlu mengonversiIEnumerable<DataRow>
keDataTable
, gunakanCopyToDataTable()
ekstensi.Di bawah ini adalah kueri dengan Ekspresi Lambda,
sumber
using System.Data;
myDataTable.Rows
sebaliknya seperti yang disarankan @JoelFan.myDataTable.Rows
adalah karenamyRow
variabel secara eksplisit dilemparkan keDataRow
. Ketika dikompilasi, kueri itu ditulis ulangmyDataTable.Rows.Cast<DataRow>().Where(myRow => (int)myRow["RowNo"] == 1)
. Secara pribadi, saya tidak menemukan panggilan ke yangAsEnumerable()
lebih rumit daripada panggilan keCast<DataRow>()
. Sejauh yang saya tahu, kinerjanya sama, jadi itu hanya masalah preferensi.sumber
(int)myRow["RowNo"]
dengan bentuk umummyRow.Field<int>("RowNo")
untuk lebih mudah mendukung jenis nullable.Bukannya mereka sengaja tidak diizinkan di DataTables, hanya saja DataTable pra-tanggal konstruksi IQneryable dan IEnumerable generik di mana pertanyaan Linq dapat dilakukan.
Kedua antarmuka membutuhkan semacam validasi keamanan jenis. DataTable tidak diketik dengan kuat. Ini adalah alasan yang sama mengapa orang tidak dapat melakukan query terhadap ArrayList, misalnya.
Agar Linq berfungsi, Anda perlu memetakan hasil Anda terhadap objek yang aman jenis dan sebagai gantinya kueri terhadap itu.
sumber
Seperti yang dikatakan @ ch00k:
Anda juga perlu menambahkan referensi proyek
System.Data.DataSetExtensions
sumber
myRow
atau penggunaanCast<DataRow>()
diRows
. Lebih baik digunakanAsEnumerable()
.System.Linq
danSystem.Data.DataSetExtensions
kemudianmyDataTable.Rows
mengembalikan koleksi enumerableDataRow
toh. Itu mungkin telah berubah, sudah satu dekade sejak saya menggunakannya.DataSet
ekstensi tidak membuatnya menjadi .NET Core atau .NET Standard, mereka sudah usang ketika saya memposting jawaban ini. Saya benar-benar tidak akan menggunakanDataSet
proyek baru, ada model akses data yang jauh lebih baik, baik untuk kemudahan pengkodean dan kinerja.DataRowCollection
tidak menerapkanIEnumerable<T>
adilIEnumerable
dan tidak bekerja dengan LINQ yang sangat diketik.bidang nama dan usia sekarang menjadi bagian dari objek kueri dan dapat diakses seperti: Console.WriteLine (query.name);
sumber
MessageBox.Show(name)
tidak ditentukan.Saya menyadari ini telah dijawab beberapa kali, tetapi hanya untuk menawarkan pendekatan lain:
Saya suka menggunakan
.Cast<T>()
metode ini, ini membantu saya menjaga kewarasan dalam melihat tipe eksplisit yang didefinisikan dan jauh di dalam hati saya pikir.AsEnumerable()
menyebutnya:atau
Seperti disebutkan dalam komentar, tidak ada majelis lain yang diperlukan karena merupakan bagian dari Linq ( Referensi )
sumber
Menggunakan LINQ untuk memanipulasi data dalam DataSet / DataTable
sumber
System.Data.DataSetExtensions
.sumber
Coba baris kueri sederhana ini:
sumber
Anda dapat menggunakan LINQ untuk objek pada koleksi Baris, seperti:
sumber
DataTable.Rows
tidak diterapkanIEnumerable
, saya tidak dapat melihat bagaimana kueri ini dapat dikompilasi.Ini adalah cara sederhana yang berfungsi untuk saya dan menggunakan ekspresi lambda:
Kemudian jika Anda menginginkan nilai tertentu:
sumber
Coba ini
sumber
Kemungkinan besar, kelas untuk DataSet, DataTable dan DataRow sudah didefinisikan dalam solusi. Jika demikian, Anda tidak perlu referensi DataSetExtensions.
Ex. Nama kelas DataSet-> CustomSet, Nama kelas DataRow-> CustomTableRow (dengan kolom yang ditentukan: RowNo, ...)
Atau (seperti yang saya inginkan)
sumber
sumber
Dalam aplikasi saya, saya menemukan bahwa menggunakan LINQ untuk Kumpulan Data dengan ekstensi AsEnumerable () untuk DataTable seperti yang disarankan dalam jawabannya sangat lambat. Jika Anda tertarik untuk mengoptimalkan kecepatan, gunakan perpustakaan Json.Net James Newtonking ( http://james.newtonking.com/json/help/index.html )
sumber
System.Data.DataRow
objek kelas berat . Tabel data berseri dan parsing membuat data ringan yang hanya terdiri dari nama kolom dan nilai setiap baris. Ketika kueri berjalan, itu akan memuat data ke dalam memori, yang untuk dataset besar mungkin melibatkan swapping. Terkadang, overhead beberapa operasi kurang dari overhead menyalin sejumlah besar data masuk dan keluar dari memori.Untuk VB.NET Kode akan terlihat seperti ini:
sumber
sumber
Contoh tentang cara mencapai ini disediakan di bawah ini:
sumber
Coba ini...
sumber
Anda bisa membuatnya bekerja dengan elegan melalui linq seperti ini:
Atau seperti linq dinamis ini (AsDynamic dipanggil langsung di DataSet):
Saya lebih suka pendekatan terakhir sedangkan yang paling fleksibel. PS: Jangan lupa menghubungkan
System.Data.DataSetExtensions.dll
referensisumber
Anda dapat mencoba ini, tetapi Anda harus yakin jenis nilai untuk setiap Kolom
sumber
Saya mengusulkan solusi berikut:
Melihat Dokumentasi DataView , hal pertama yang dapat kita lihat adalah ini:
Apa yang saya dapatkan dari ini adalah bahwa DataTable hanya dimaksudkan untuk menyimpan data dan DataView ada memungkinkan kita untuk "query" terhadap DataTable.
Inilah cara kerjanya dalam kasus khusus ini:
Anda mencoba menerapkan Pernyataan SQL
dalam "Bahasa DataTable". Dalam C # kita akan membacanya seperti ini:
yang terlihat dalam C # seperti ini:
sumber
sumber