Apa yang ingin Anda capai dengan Daftar yang tidak dapat Anda lakukan dengan DataRowCollection Anda?
Jason Kealey
Milik saya terlambat tetapi harapan akan bermanfaat. Solusi yang
berfungsi
Jawaban:
276
Jika Anda menggunakan .NET 3.5, Anda dapat menggunakan DataTableExtensions.AsEnumerable(metode ekstensi) dan kemudian jika Anda benar-benar membutuhkan, Anda List<DataRow>hanya IEnumerable<DataRow>dapat menelepon Enumerable.ToList:
@Pandiya: Ada berbagai cara untuk mengubah data menjadi JSON di .NET. Secara pribadi saya selalu menggunakan perpustakaan JSON.NET, tetapi ada pendekatan lain juga.
Kode di atas mungkin tidak berfungsi bcs. dt.Rows belum menerapkan 'AsEnumerable'. Ini dapat diperbaiki seperti di bawah ini: emp = (dari baris DataRow di dt.AsEnumerable () pilih Karyawan baru {_FirstName = baris ["FirstName"]. ToString (), _LastName = baris ["Last_Name"]. ToString ()}) .ToList ();
Navin Pandit
37
Dengan C # 3.0 dan System.Data.DataSetExtensions.dll,
melakukan ini telah membantu kinerja dari hanya menggunakan foreach atas datarow sebanyak 50% waktu.
lloydom
33
Anda bisa menggunakannya
List<DataRow>list=newList<DataRow>(dt.Select());
dt.Select()akan mengembalikan semua baris dalam tabel Anda, sebagai array flatows, dan Listkonstruktor menerima array objek sebagai argumen untuk mengisi daftar Anda dengan awalnya.
Tidak berfungsi - lihat dotnetfiddle.net/I22r2c Perlu juga dicatat bahwa menggunakan Reflection lambat dan tidak direkomendasikan dalam kode kinerja kritis.
Almenon
Anda perlu menambahkan informasi tipe data untuk kolom. DataTable dt = DataTable baru (); dt.Columns.Add ("id", typeof (Int32)); dt.Columns.Add ("name", typeof (String)); dt.Columns.Add ("foo", typeof (DateTime)); for (int i = 0; i <= 1000; i ++) {dt.Rows.Add (i, "foo", DateTime.Now);}
Rahul Garg
Bekerja sekarang. Terima kasih.
Almenon
14
Jika Anda hanya ingin daftar nilai dari bidang int "ID" dikembalikan, Anda dapat menggunakan ...
List<int> ids =(from row in dt.AsEnumerable()selectConvert.ToInt32(row["ID"])).ToList();
Saya telah menambahkan beberapa modifikasi pada kode dari jawaban ini ( https://stackoverflow.com/a/24588210/4489664 ) karena untuk Jenis yang dapat dibatalkan akan mengembalikan pengecualian
publicstaticList<T>DataTableToList<T>(thisDataTable table)where T:new(){List<T>list=newList<T>();var typeProperties =typeof(T).GetProperties().Select(propertyInfo =>new{PropertyInfo= propertyInfo,Type=Nullable.GetUnderlyingType(propertyInfo.PropertyType)?? propertyInfo.PropertyType}).ToList();foreach(var row in table.Rows.Cast<DataRow>()){
T obj =new T();foreach(var typeProperty in typeProperties){objectvalue= row[typeProperty.PropertyInfo.Name];object safeValue =value==null||DBNull.Value.Equals(value)?null:Convert.ChangeType(value, typeProperty.Type);
typeProperty.PropertyInfo.SetValue(obj, safeValue,null);}list.Add(obj);}returnlist;}
Saya menghapus kelas karena dapat bekerja dengan struct juga.
Mickey Perlstein
Ini bekerja dengan sangat baik, kerja bagus. Jika ada yang ingin bermain-main dengan kode ini, saya membuat biola .net di tautan ini: dotnetfiddle.net/mTKevy
Almenon
@Almenon Saya telah menambahkan modifikasi kecil, itu harus sedikit meningkatkan kinerja
Bondaryuk Vladimir
11
using System.Data;var myEnumerable = myDataTable.AsEnumerable();List<MyClass> myClassList =(from item in myEnumerable
selectnewMyClass{MyClassProperty1= item.Field<string>("DataTableColumnName1"),MyClassProperty2= item.Field<string>("DataTableColumnName2")}).ToList();
DataTable.Select() tidak memberikan Baris dalam urutan mereka hadir di datatable.
Jika pesanan penting, saya merasa iterasi pada koleksi datarow dan membentuk Daftar adalah cara yang tepat untuk pergi atau Anda juga bisa menggunakan kelebihan DataTable.Select(string filterexpression, string sort).
Tapi kelebihan ini mungkin tidak menangani semua pemesanan (seperti pesanan per kasus ...) yang disediakan SQL.
DataTable dt;// datatable should contains datacolumns with Id,NameList<Employee> employeeList=newList<Employee>();// Employee should contain EmployeeId, EmployeeName as propertiesforeach(DataRow dr in dt.Rows){
employeeList.Add(newEmployee{EmployeeId=dr.Id,EmplooyeeName=dr.Name});}
/* This is a generic method that will convert any type of DataTable to a List
*
*
* Example : List< Student > studentDetails = new List< Student >();
* studentDetails = ConvertDataTable< Student >(dt);
*
* Warning : In this case the DataTable column's name and class property name
* should be the same otherwise this function will not work properly
*/
Berikut ini adalah dua fungsi di mana jika kita melewati kelas DataTable dan yang ditentukan pengguna. Kemudian akan mengembalikan Daftar kelas itu dengan data DataTable.
publicstaticList<T>ConvertDataTable<T>(DataTable dt){List<T> data =newList<T>();foreach(DataRow row in dt.Rows){
T item =GetItem<T>(row);
data.Add(item);}return data;}privatestatic T GetItem<T>(DataRow dr){Type temp =typeof(T);
T obj =Activator.CreateInstance<T>();foreach(DataColumn column in dr.Table.Columns){foreach(PropertyInfo pro in temp.GetProperties()){//in case you have a enum/GUID datatype in your model//We will check field's dataType, and convert the value in it.if(pro.Name== column.ColumnName){try{var convertedValue =GetValueByDataType(pro.PropertyType, dr[column.ColumnName]);
pro.SetValue(obj, convertedValue,null);}catch(Exception e){//ex handle code throw;}//pro.SetValue(obj, dr[column.ColumnName], null);}elsecontinue;}}return obj;}
Metode ini akan memeriksa tipe data bidang, dan mengonversi nilai dataTable ke tipe data itu.
Ubah nama kelas Siswa dan nilai dt berdasarkan kebutuhan Anda. Dalam hal ini nama kolom DataTable dan nama properti kelas harus sama jika tidak fungsi ini tidak akan berfungsi dengan baik.
Terima kasih atas jawaban anda. Akan lebih bagus jika Anda juga menambahkan penjelasan singkat dan beberapa komentar pada kode Anda. Ini membantu orang untuk memahami jawaban Anda dengan lebih baik.
Andre Hofmeister
0
Ini bekerja untuk saya:
Perlu setidaknya. Net Framework 3.5,
Kode di bawah ini menampilkan DataRow beralih ke Generic. Dapat dihitung, comboBox1 telah digunakan untuk ilustrasi yang lebih baik.
using System.Linq;DataTable dt =newDataTable();
dt = myClass.myMethod();List<object>list=(from row in dt.AsEnumerable()select(row["name"])).ToList();
comboBox1.DataSource=list;
publicstaticclassExtensions{#region Convert Datatable To ListpublicstaticIList<T>ToList<T>(thisDataTable table)where T :new(){IList<PropertyInfo> properties =typeof(T).GetProperties().ToList();IList<T> result =newList<T>();foreach(var row in table.Rows){var item =CreateItemFromRow<T>((DataRow)row, properties);
result.Add(item);}return result;}privatestatic T CreateItemFromRow<T>(DataRow row,IList<PropertyInfo> properties)where T :new(){
T item =new T();foreach(var property in properties){
property.SetValue(item, row[property.Name],null);}return item;}#endregion}
Untuk menetapkan baris DataTable ke Daftar kelas umum
List<Candidate> temp =newList<Candidate>();//List that holds the Candidate Class,//Note:The Candidate class contains RollNo,Name and Department//tb is DataTable
temp =(fromDataRow dr in tb.RowsselectnewCandidate(){RollNO=Convert.ToInt32(dr["RollNO"]),Name= dr["Name"].ToString(),Department= dr["Department"].ToString(),}).ToList();
privatestaticList<T>ConvertDataTable<T>(DataTable dt){List<T> data =newList<T>();foreach(DataRow row in dt.Rows){
T item =GetItem<T>(row);
data.Add(item);}return data;}privatestatic T GetItem<T>(DataRow dr){Type temp =typeof(T);
T obj =Activator.CreateInstance<T>();foreach(DataColumn column in dr.Table.Columns){foreach(PropertyInfo pro in temp.GetProperties()){if(pro.Name== column.ColumnName)
pro.SetValue(obj, dr[column.ColumnName].ToString(),null);elsecontinue;}}return obj;}
Jawaban:
Jika Anda menggunakan .NET 3.5, Anda dapat menggunakan
DataTableExtensions.AsEnumerable
(metode ekstensi) dan kemudian jika Anda benar-benar membutuhkan, AndaList<DataRow>
hanyaIEnumerable<DataRow>
dapat meneleponEnumerable.ToList
:atau
sumber
list
ke json.sumber
Dengan C # 3.0 dan System.Data.DataSetExtensions.dll,
sumber
Anda bisa menggunakannya
dt.Select()
akan mengembalikan semua baris dalam tabel Anda, sebagai array flatows, danList
konstruktor menerima array objek sebagai argumen untuk mengisi daftar Anda dengan awalnya.sumber
Anda dapat membuat fungsi ekstensi sebagai:
sumber
Jika Anda hanya ingin daftar nilai dari bidang int "ID" dikembalikan, Anda dapat menggunakan ...
sumber
Saya telah menambahkan beberapa modifikasi pada kode dari jawaban ini ( https://stackoverflow.com/a/24588210/4489664 ) karena untuk Jenis yang dapat dibatalkan akan mengembalikan pengecualian
sumber
sumber
Sekali lagi, menggunakan 3.5 Anda dapat melakukannya seperti:
BRGDS
sumber
Berikut adalah metode ekstensi DataTable yang mengubah DataTable ke daftar umum.
https://gist.github.com/gaui/a0a615029f1327296cf8
Pemakaian:
sumber
Cara yang lebih 'ajaib', dan tidak perlu. NET 3.5.
Jika, misalnya,
DBDatatable
mengembalikan satu kolom Guids (uniqueidentifier dalam SQL) maka Anda dapat menggunakan:sumber
sumber
DataTable.Select()
tidak memberikan Baris dalam urutan mereka hadir di datatable.Jika pesanan penting, saya merasa iterasi pada koleksi datarow dan membentuk Daftar adalah cara yang tepat untuk pergi atau Anda juga bisa menggunakan kelebihan
DataTable.Select(string filterexpression, string sort)
.Tapi kelebihan ini mungkin tidak menangani semua pemesanan (seperti pesanan per kasus ...) yang disediakan SQL.
sumber
sumber
Gunakan
System.Data
namespace maka Anda akan mendapatkan.AsEnumerable()
.sumber
sumber
Ini bekerja untuk saya: Perlu setidaknya. Net Framework 3.5, Kode di bawah ini menampilkan DataRow beralih ke Generic. Dapat dihitung, comboBox1 telah digunakan untuk ilustrasi yang lebih baik.
sumber
Keluaran
sumber
Kita dapat menggunakan Metode Generik untuk mengkonversi
DataTable
keList
bukan secara manual mengkonversiDataTable
keList
.Catatan:
DataTable
'sColumnName
danType
' sPropertyName
harus sama.Panggil Metode di bawah ini:
sumber
Anda dapat menggunakan metode generik seperti itu untuk daftar data ke daftar generik
sumber
Konversi
DataTable
ke GenerikDictionary
sumber
Gunakan Ekstensi:
sumber
Untuk menetapkan baris DataTable ke Daftar kelas umum
sumber
Cara termudah untuk Mengubah DataTable ke dalam daftar kelas Generik
menggunakan Newtonsoft.Json;
sumber
Anda dapat menggunakan dua fungsi Generik berikut
dan gunakan sebagai berikut
sumber
Tautan ke Contoh DotNetFiddle yang berfungsi
}
sumber