У меня есть строго типизированный DataTable типа MyType
, я хотел бы преобразовать его в List<MyType>
.
Как я могу это сделать ?
Спасибо.
У меня есть строго типизированный DataTable типа MyType
, я хотел бы преобразовать его в List<MyType>
.
Как я могу это сделать ?
Спасибо.
Следующее делает это в одной строке:
dataTable.Rows.OfType<DataRow>()
.Select(dr => dr.Field<MyType>(columnName)).ToList();
[Изменить: добавьте ссылку на System.Data.DataSetExtensions
в свой проект, если он не компилируется]
columnName
— это имя любого столбца, имеющего его MyType
. Если, с другой стороны, каждая строка имеет несколько столбцов, каждый из которых представляет свойство MyType
, то ответ Ричарда правильный.
- person Yuriy Faktorovich; 13.02.2020
Существуют методы расширения Linq для DataTable.
Добавить ссылку на: System.Data.DataSetExtensions.dll
Затем включите пространство имен: using System.Data.DataSetExtensions
Наконец, вы можете использовать расширения Linq для DataSet и DataTables:
var matches = myDataSet.Tables.First().Where(dr=>dr.Field<int>("id") == 1);
В .Net 2.0 вы все равно можете добавить общий метод:
public static List<T> ConvertRowsToList<T>( DataTable input, Convert<DataRow, T> conversion) {
List<T> retval = new List<T>()
foreach(DataRow dr in input.Rows)
retval.Add( conversion(dr) );
return retval;
}
Convert
? Вы имеете в виду Converter
?
- person MoonKnight; 27.03.2012
what is the Convert keyword here? Do you mean Converter?
На самом деле он имеет в виду передать func<DataRow, T> conversion
, то есть любой delegate/function
ожидать datarow
, и на выходе будет T
сущность ..
- person Moumit; 13.12.2013
.net 2.0
.. Вот ссылка .. http://codenicely.blogspot.in/2012/02/converting-your-datatable-into-list.html
- person Moumit; 13.12.2013
Таблица данных для списка
#region "getobject filled object with property reconized"
public List<T> ConvertTo<T>(DataTable datatable) where T : new()
{
List<T> Temp = new List<T>();
try
{
List<string> columnsNames = new List<string>();
foreach (DataColumn DataColumn in datatable.Columns)
columnsNames.Add(DataColumn.ColumnName);
Temp = datatable.AsEnumerable().ToList().ConvertAll<T>(row => getObject<T>(row, columnsNames));
return Temp;
}
catch
{
return Temp;
}
}
public T getObject<T>(DataRow row, List<string> columnsName) where T : new()
{
T obj = new T();
try
{
string columnname = "";
string value = "";
PropertyInfo[] Properties;
Properties = typeof(T).GetProperties();
foreach (PropertyInfo objProperty in Properties)
{
columnname = columnsName.Find(name => name.ToLower() == objProperty.Name.ToLower());
if (!string.IsNullOrEmpty(columnname))
{
value = row[columnname].ToString();
if (!string.IsNullOrEmpty(value))
{
if (Nullable.GetUnderlyingType(objProperty.PropertyType) != null)
{
value = row[columnname].ToString().Replace("$", "").Replace(",", "");
objProperty.SetValue(obj, Convert.ChangeType(value, Type.GetType(Nullable.GetUnderlyingType(objProperty.PropertyType).ToString())), null);
}
else
{
value = row[columnname].ToString().Replace("%", "");
objProperty.SetValue(obj, Convert.ChangeType(value, Type.GetType(objProperty.PropertyType.ToString())), null);
}
}
}
}
return obj;
}
catch
{
return obj;
}
}
#endregion
Коллекция IEnumerable To Datatable
#region "New DataTable"
public DataTable ToDataTable<T>(IEnumerable<T> collection)
{
DataTable newDataTable = new DataTable();
Type impliedType = typeof(T);
PropertyInfo[] _propInfo = impliedType.GetProperties();
foreach (PropertyInfo pi in _propInfo)
newDataTable.Columns.Add(pi.Name, pi.PropertyType);
foreach (T item in collection)
{
DataRow newDataRow = newDataTable.NewRow();
newDataRow.BeginEdit();
foreach (PropertyInfo pi in _propInfo)
newDataRow[pi.Name] = pi.GetValue(item, null);
newDataRow.EndEdit();
newDataTable.Rows.Add(newDataRow);
}
return newDataTable;
}
Метод ConvertToList, который опубликован ниже и использует отражение, отлично работает для меня. Спасибо.
Я сделал небольшую модификацию, чтобы заставить его работать с преобразованиями в типах свойств T.
public List<T> ConvertToList<T>(DataTable dt)
{
var columnNames = dt.Columns.Cast<DataColumn>()
.Select(c => c.ColumnName)
.ToList();
var properties = typeof(T).GetProperties();
return dt.AsEnumerable().Select(row =>
{
var objT = Activator.CreateInstance<T>();
foreach (var pro in properties)
{
if (columnNames.Contains(pro.Name))
{
PropertyInfo pI = objT.GetType().GetProperty(pro.Name);
pro.SetValue(objT, row[pro.Name] == DBNull.Value ? null : Convert.ChangeType(row[pro.Name], pI.PropertyType));
}
}
return objT;
}).ToList();
}
Надеюсь, поможет. С Уважением.
IEnumerable<DataRow> rows = dataTable.AsEnumerable();
(System.Data.DataSetExtensions.dll)IEnumerable<DataRow> rows = dataTable.Rows.OfType<DataRow>();
(System.Core.dll)Отлично работает!!
Я сделал несколько обновлений из ответа @suneelsarraf и удалил Convert.ChangeType()
, потому что он продолжает выдавать Invalid Cast Exception
. Взгляните!
#region *** Convert DT to List<Object> ***
private List<I> ConvertTo<I>(DataTable datatable) where I : class
{
List<I> lstRecord = new List<I>();
try
{
List<string> columnsNames = new List<string>();
foreach (DataColumn DataColumn in datatable.Columns)
columnsNames.Add(DataColumn.ColumnName);
lstRecord = datatable.AsEnumerable().ToList().ConvertAll<I>(row => GetObject<I>(row, columnsNames));
return lstRecord;
}
catch
{
return lstRecord;
}
}
private I GetObject<I>(DataRow row, List<string> columnsName) where I : class
{
I obj = (I)Activator.CreateInstance(typeof(I));
try
{
PropertyInfo[] Properties = typeof(I).GetProperties();
foreach (PropertyInfo objProperty in Properties)
{
string columnname = columnsName.Find(name => name.ToLower() == objProperty.Name.ToLower());
if (!string.IsNullOrEmpty(columnname))
{
object dbValue = row[columnname];
if (dbValue != DBNull.Value)
{
if (Nullable.GetUnderlyingType(objProperty.PropertyType) != null)
{
objProperty.SetValue(obj, Convert.ChangeType(dbValue, Type.GetType(Nullable.GetUnderlyingType(objProperty.PropertyType).ToString())), null);
}
else
{
objProperty.SetValue(obj, Convert.ChangeType(dbValue, Type.GetType(objProperty.PropertyType.ToString())), null);
}
}
}
}
return obj;
}
catch(Exception ex)
{
return obj;
}
}
#endregion
И это то, как вы используете в своем коде.
// Other Codes Here
var lstResult = ConvertTo<TEntity>(dataTableName); // Convert DT to List<TEntity>
Развлекайтесь! Будьте в безопасности в 2020 году.
Предполагая, что ваши DataRow
наследуются от вашего собственного типа, скажем, MyDataRowType
, это должно работать:
List<MyDataRowType> list = new List<MyDataRowType>();
foreach(DataRow row in dataTable.Rows)
{
list.Add((MyDataRowType)row);
}
Это предполагает, как вы сказали в комментарии, что вы используете .NET 2.0 и не имеете доступа к методам расширения LINQ.
пожалуйста, попробуйте этот код:
public List<T> ConvertToList<T>(DataTable dt)
{
var columnNames = dt.Columns.Cast<DataColumn>()
.Select(c => c.ColumnName)
.ToList();
var properties = typeof(T).GetProperties();
return dt.AsEnumerable().Select(row =>
{
var objT = Activator.CreateInstance<T>();
foreach (var pro in properties)
{
if (columnNames.Contains(pro.Name))
pro.SetValue(objT, row[pro.Name]);
}
return objT;
}).ToList();
}
pro.SetValue(objT, row[pro.Name] == DBNull.Value ? default(T) : row[pro.Name]);
- person Amélie Dupré; 25.02.2020
Создайте список с типом<DataRow>
, расширив вызов datatable
с помощью AsEnumerable
.
var mylist = dt.AsEnumerable().ToList();
Ваше здоровье!! Счастливого кодирования
спасибо за все сообщения.... Я сделал это с помощью Linq Query, чтобы просмотреть это, перейдите по следующей ссылке
http://codenicely.blogspot.com/2012/02/converting-your-datatable-into-list.html
Попробуйте этот код, и это самый простой способ преобразовать данные в список
List<DataRow> listtablename = dataTablename.AsEnumerable().ToList();
Существует небольшой пример, который вы можете использовать
DataTable dt = GetCustomersDataTable(null);
IEnumerable<SelectListItem> lstCustomer = dt.AsEnumerable().Select(x => new SelectListItem()
{
Value = x.Field<string>("CustomerId"),
Text = x.Field<string>("CustomerDescription")
}).ToList();
return lstCustomer;
вы можете преобразовать свой datatable в список. проверьте следующую ссылку
https://stackoverflow.com/a/35171050/1805776
public static class Helper
{
public static List<T> DataTableToList<T>(this DataTable dataTable) where T : new()
{
var dataList = new List<T>();
//Define what attributes to be read from the class
const System.Reflection.BindingFlags flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance;
//Read Attribute Names and Types
var objFieldNames = typeof(T).GetProperties(flags).Cast<System.Reflection.PropertyInfo>().
Select(item => new
{
Name = item.Name,
Type = Nullable.GetUnderlyingType(item.PropertyType) ?? item.PropertyType
}).ToList();
//Read Datatable column names and types
var dtlFieldNames = dataTable.Columns.Cast<DataColumn>().
Select(item => new
{
Name = item.ColumnName,
Type = item.DataType
}).ToList();
foreach (DataRow dataRow in dataTable.AsEnumerable().ToList())
{
var classObj = new T();
foreach (var dtField in dtlFieldNames)
{
System.Reflection.PropertyInfo propertyInfos = classObj.GetType().GetProperty(dtField.Name);
var field = objFieldNames.Find(x => x.Name == dtField.Name);
if (field != null)
{
if (propertyInfos.PropertyType == typeof(DateTime))
{
propertyInfos.SetValue
(classObj, convertToDateTime(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(Nullable<DateTime>))
{
propertyInfos.SetValue
(classObj, convertToDateTime(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(int))
{
propertyInfos.SetValue
(classObj, ConvertToInt(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(long))
{
propertyInfos.SetValue
(classObj, ConvertToLong(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(decimal))
{
propertyInfos.SetValue
(classObj, ConvertToDecimal(dataRow[dtField.Name]), null);
}
else if (propertyInfos.PropertyType == typeof(String))
{
if (dataRow[dtField.Name].GetType() == typeof(DateTime))
{
propertyInfos.SetValue
(classObj, ConvertToDateString(dataRow[dtField.Name]), null);
}
else
{
propertyInfos.SetValue
(classObj, ConvertToString(dataRow[dtField.Name]), null);
}
}
else
{
propertyInfos.SetValue
(classObj, Convert.ChangeType(dataRow[dtField.Name], propertyInfos.PropertyType), null);
}
}
}
dataList.Add(classObj);
}
return dataList;
}
private static string ConvertToDateString(object date)
{
if (date == null)
return string.Empty;
return date == null ? string.Empty : Convert.ToDateTime(date).ConvertDate();
}
private static string ConvertToString(object value)
{
return Convert.ToString(ReturnEmptyIfNull(value));
}
private static int ConvertToInt(object value)
{
return Convert.ToInt32(ReturnZeroIfNull(value));
}
private static long ConvertToLong(object value)
{
return Convert.ToInt64(ReturnZeroIfNull(value));
}
private static decimal ConvertToDecimal(object value)
{
return Convert.ToDecimal(ReturnZeroIfNull(value));
}
private static DateTime convertToDateTime(object date)
{
return Convert.ToDateTime(ReturnDateTimeMinIfNull(date));
}
public static string ConvertDate(this DateTime datetTime, bool excludeHoursAndMinutes = false)
{
if (datetTime != DateTime.MinValue)
{
if (excludeHoursAndMinutes)
return datetTime.ToString("yyyy-MM-dd");
return datetTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
}
return null;
}
public static object ReturnEmptyIfNull(this object value)
{
if (value == DBNull.Value)
return string.Empty;
if (value == null)
return string.Empty;
return value;
}
public static object ReturnZeroIfNull(this object value)
{
if (value == DBNull.Value)
return 0;
if (value == null)
return 0;
return value;
}
public static object ReturnDateTimeMinIfNull(this object value)
{
if (value == DBNull.Value)
return DateTime.MinValue;
if (value == null)
return DateTime.MinValue;
return value;
}
}
.ToDictionary
- person Keith   schedule 16.09.2009