J'ai un DataTable fortement typé de type MyType
, je voudrais le convertir en List<MyType>
.Convertir DataTable à la liste <T>
Comment est-ce que je peux faire ceci?
Merci.
J'ai un DataTable fortement typé de type MyType
, je voudrais le convertir en List<MyType>
.Convertir DataTable à la liste <T>
Comment est-ce que je peux faire ceci?
Merci.
Il existe des méthodes d'extension Linq pour DataTable.
Ajouter référence à: System.Data.DataSetExtensions.dll
comprennent alors l'espace de noms: using System.Data.DataSetExtensions
Enfin, vous pouvez utiliser des extensions Linq sur DataSet et DataTable:
var matches = myDataSet.Tables.First().Where(dr=>dr.Field<int>("id") == 1);
.Net 2.0 vous pouvez toujours ajouter générique méthode:
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;
}
Y at-il un moyen facile si coincé avec .NET 2.0? – auujay
+1 Sweeeeeet! Mais quel est le mot clé 'Convert' ici? Voulez-vous dire 'Converter'? – MoonKnight
@Keith - Il doit être Convert ** er **
En supposant que votre DataRow
s héritent de votre propre type, disent MyDataRowType
, cela devrait fonctionner:
List<MyDataRowType> list = new List<MyDataRowType>();
foreach(DataRow row in dataTable.Rows)
{
list.Add((MyDataRowType)row);
}
Cela suppose, comme vous l'avez dit dans un commentaire, que vous utilisez .NET 2.0 et n'ont pas accès aux méthodes d'extension LINQ.
pourquoi ne pas simplement faire une liste
@Mike: Puisque l'OP dit qu'il a un DataTable fortement typé, je suppose qu'il préférerait garder ce typage fort dans ses résultats. –
@Adam, oui je voudrais garder le typage fort. J'ai maintenant accès à Linq dans ce projet –
qui suit le fait d'une seule ligne:
dataTable.Rows.OfType<DataRow>()
.Select(dr => dr.Field<MyType>(columnName)).ToList();
[Modifier : Ajouter une référence à System.Data.DataSetExtensions
à votre projet si cela ne compile pas]
Quelle est la valeur de columnName ici? – user123456
IEnumerable<DataRow> rows = dataTable.AsEnumerable();
(System.Data .DataSetExtensions.dll)IEnumerable<DataRow> rows = dataTable.Rows.OfType<DataRow>();
(System.Core.dll)Tableau de données Liste
#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
collection 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;
}
Merci pour tous les messages .... je l'ai fait avec l'aide de requête LINQ, pour voir ce s'il vous plaît visitez le lien suivant
http://codenicely.blogspot.com/2012/02/converting-your-datatable-into-list.html
Créer une liste ty pe par extension de la date avec l'appel AsEnumerable.
var mylist = dt.AsEnumerable(). ToList();
À la vôtre !!Bonne programmation
Un DataTable n'a pas de méthode AsEnumerable à moins que votre solution nécessite une référence et que vous l'utilisiez pour fonctionner. – johnstaveley
Essayez ce code, ce qui est plus simple de convertir datatable à la liste
List<DataRow> listtablename = dataTablename.AsEnumerable().ToList();
Je reçois cette erreur; \t 'System.Data.EnumerableRowCollection
trouvé maintenant, ajouté en utilisant 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()
Nice, très élégant. –
qu'est-ce que
MyType est un objet que vous créer avant le code ci-dessus avec les mêmes variables (ID, Description, Balance) –
s'il vous plaît essayer ce code:
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();
}
La méthode ConvertToList qui est affiché ci-dessous et utilisations la réflexion fonctionne parfaitement pour moi. Merci.
J'ai fait une légère modification pour le faire fonctionner avec des conversions sur les types de propriétés 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();
}
Espérons que cela aide. Cordialement.
Merci, Gilda. Cette fonction fonctionne vraiment bien et elle est également rapide. – windchaser
vous pouvez convertir votre datatable en liste. consultez le lien suivant
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;
}
}
Il y a un peu example que vous pouvez utiliser
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;
Il fait probablement plus de scènes à convertir DataTable dans le dictionnaire de liste. – Vadim
@Vadim: Qu'est-ce qui vous ferait dire ça? –
DataTable a des lignes et des colonnes. Le dictionnaire représente beaucoup mieux cette structure que List. – Vadim