Convert DataTable to List<T>

C#.NetGenericsDatatable

C# Problem Overview


I have an strongly typed DataTable of type MyType, I'd like convert it in a List<MyType>.

How can I do this ?

Thanks.

C# Solutions


Solution 1 - C#

The following does it in a single line:

dataTable.Rows.OfType<DataRow>()
    .Select(dr => dr.Field<MyType>(columnName)).ToList();

[Edit: Add a reference to System.Data.DataSetExtensions to your project if this does not compile]

Solution 2 - C#

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()

Solution 3 - C#

There are Linq extension methods for DataTable.

Add reference to: System.Data.DataSetExtensions.dll

Then include the namespace: using System.Data.DataSetExtensions

Finally you can use Linq extensions on DataSet and DataTables:

var matches = myDataSet.Tables.First().Where(dr=>dr.Field<int>("id") == 1);

On .Net 2.0 you can still add generic method:

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;
}

Solution 4 - C#

Data table to List

    #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 collection 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;
    }

Solution 5 - C#

The method ConvertToList that is posted below and uses reflection works perfectly for me. Thanks.

I made a slight modification to make it work with conversions on the T property types.

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();
}

Hope it helps. Regards.

Solution 6 - C#

  1. IEnumerable<DataRow> rows = dataTable.AsEnumerable(); (System.Data.DataSetExtensions.dll)
  2. IEnumerable<DataRow> rows = dataTable.Rows.OfType<DataRow>(); (System.Core.dll)

Solution 7 - C#

That pretty works!!

I made some updates from @suneelsarraf's answer and I removed Convert.ChangeType() because it keeps throwing Invalid Cast Exception. Have a take a look!

#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

And this is how you use in your code.

// Other Codes Here
var lstResult = ConvertTo<TEntity>(dataTableName); // Convert DT to List<TEntity>

Have Fun! Be Safe in 2020.

Solution 8 - C#

Create a list with type<DataRow> by extend the datatable with AsEnumerable call.

var mylist = dt.AsEnumerable().ToList();

Cheers!! Happy Coding

Solution 9 - C#

Assuming your DataRows inherit from your own type, say MyDataRowType, this should work:

List<MyDataRowType> list = new List<MyDataRowType>();

foreach(DataRow row in dataTable.Rows)
{
    list.Add((MyDataRowType)row);
}

This is assuming, as you said in a comment, that you're using .NET 2.0 and don't have access to the LINQ extension methods.

Solution 10 - C#

please try this 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();
}

Solution 11 - C#

thanks for all of posts.... I have done it with using Linq Query, to view this please visit the following link

http://codenicely.blogspot.com/2012/02/converting-your-datatable-into-list.html

Solution 12 - C#

Try this code and This is easiest way to convert datatable to list

List<DataRow> listtablename = dataTablename.AsEnumerable().ToList();

Solution 13 - C#

you can convert your datatable to list. check the following link

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;
    }
}

Solution 14 - C#

There is a little example that you can use

            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;

     

Solution 15 - C#

I know it a too late

but actually there is a simple way with help of Newtonsoft Json:

var json = JsonConvert.SerializeObject(dataTable);
var YourConvertedDataType = JsonConvert.DeserializeObject<YourDataType>(json);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKris-IView Question on Stackoverflow
Solution 1 - C#Yuriy FaktorovichView Answer on Stackoverflow
Solution 2 - C#Richard YSView Answer on Stackoverflow
Solution 3 - C#KeithView Answer on Stackoverflow
Solution 4 - C#suneelsarrafView Answer on Stackoverflow
Solution 5 - C#GildaView Answer on Stackoverflow
Solution 6 - C#abatishchevView Answer on Stackoverflow
Solution 7 - C#zawView Answer on Stackoverflow
Solution 8 - C#user2660592View Answer on Stackoverflow
Solution 9 - C#Adam RobinsonView Answer on Stackoverflow
Solution 10 - C#HaoView Answer on Stackoverflow
Solution 11 - C#Khalid RafiqueView Answer on Stackoverflow
Solution 12 - C#Avinash shindeView Answer on Stackoverflow
Solution 13 - C#vickyView Answer on Stackoverflow
Solution 14 - C#Ivan FurmanskiView Answer on Stackoverflow
Solution 15 - C#Ali AminiView Answer on Stackoverflow