У меня есть строго типизированный DataTable типа MyType
, я бы хотел преобразовать его в List<MyType>
.Преобразование DataTable в список <T>
Как это сделать?
Спасибо.
У меня есть строго типизированный DataTable типа MyType
, я бы хотел преобразовать его в List<MyType>
.Преобразование DataTable в список <T>
Как это сделать?
Спасибо.
Существуют методы расширения 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;
}
Есть ли простой способ, если вы используете .NET 2.0? – auujay
+1 Sweeeeeet! Но каково здесь ключевое слово Convert? Вы имеете в виду «Конвертер»? – MoonKnight
@ Keith - Он должен быть преобразован ** er **
Если предположить, что ваши DataRow
s наследовать от вашего собственного типа, скажем MyDataRowType
, это должно работать:
List<MyDataRowType> list = new List<MyDataRowType>();
foreach(DataRow row in dataTable.Rows)
{
list.Add((MyDataRowType)row);
}
Это предполагает, что, как вы сказали в комментариях, что вы используете .NET 2.0 и не имеют доступа к методам расширения LINQ.
почему бы не просто составить список
@Mike: Поскольку OP говорит, что у него сильно типизированный DataTable, я бы предположил, что он предпочел бы сохранить эту сильную типизацию в своих результатах. –
@ Адам, да, я бы хотел сохранить сильную типизацию. У меня есть доступ к Linq сейчас в этом проекте –
Следующие делает это в одной строке:
dataTable.Rows.OfType<DataRow>()
.Select(dr => dr.Field<MyType>(columnName)).ToList();
[Edit: Добавить ссылку на System.Data.DataSetExtensions
ваш проект, если это не компилирует]
Что такое значение columnName? – user123456
IEnumerable<DataRow> rows = dataTable.AsEnumerable();
(System.Data .DataSetExtensions.dll)IEnumerable<DataRow> rows = dataTable.Rows.OfType<DataRow>();
(System.Core.dll)таблица данных в список
#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 коллекцию Чтобы 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;
}
спасибо за все посты .... Я сделал это с помощью Linq запроса, для этого, пожалуйста, посетите следуя ссылке
http://codenicely.blogspot.com/2012/02/converting-your-datatable-into-list.html
Создать список с ти pe, увеличивая число данных с помощью вызова AsEnumerable.
var mylist = dt.AsEnumerable(). ToList();
Cheers !!Счастливый Coding
DataTable не имеет метода AsEnumerable, если вашему решению не требуется ссылка и использование для работы. – johnstaveley
Попробуйте этот код и это самый простой способ конвертировать DataTable в список
List<DataRow> listtablename = dataTablename.AsEnumerable().ToList();
Я получаю эту ошибку; \t «System.Data.EnumerableRowCollection
теперь вычислен, добавлен с использованием System.Linq; – Salim
List<MyType> listName = dataTableName.AsEnumerable().Select(m => new MyType()
{
ID = m.Field<string>("ID"),
Description = m.Field<string>("Description"),
Balance = m.Field<double>("Balance"),
}).ToList()
Ницца, очень элегантный. –
Что такое
MyType - это объект, который вы создали бы перед кодом, показанным выше, с теми же переменными (ID, Описание, Баланс) –
пожалуйста попробуйте этот код:
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();
}
метод 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();
}
Надеюсь, что это поможет. С уважением.
Спасибо, Гильда. Эта функция действительно работает хорошо, и она также быстро прекращается. – windchaser
Вы можете конвертировать данные в список. проверьте ссылку
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;
}
}
Существует немного example, что вы можете использовать
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 в словарь, чем список. – Vadim
@ Вадим: Что бы вы так сказали? –
DataTable имеет строки и столбцы. Словарь представляет эту структуру намного лучше, чем List. – Vadim