Click here to Skip to main content
15,916,835 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
How to handle null-able type convert datatable to list

C#
public static class DataTableToList
   {
       public static List<T> ToList<T>(this DataTable table) where T : class, new()
       {
           try
           {
               List<T> list = new List<T>();

               foreach (var row in table.AsEnumerable())
               {
                   T obj = new T();

                   foreach (var prop in obj.GetType().GetProperties())
                   {
                       try
                       {
                           PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
                           propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null);
                       }
                       catch
                       {
                           continue;
                       }
                   }

                   list.Add(obj);
               }

               return list;
           }
           catch
           {
               return null;
           }
       }
   }


What I have tried:

How to handle null-able type convert datatable to list
Posted
Updated 22-Aug-16 7:37am
Comments
Philippe Mori 22-Aug-16 19:02pm    
continue is the catch block is useless...

All you need to do is in your existing code, add a line to check if the data row value is null and also if the property of <T> is nullable too:

C#
if(row[prop.Name] == DBNull.Value /* or == null */
   && prop.PropertyType.IsValueType
   && Nullable.GetUnderlyingType(prop.PropertyType) != null)
   // if property is nullable, underlying nullable type will eval as true.
{
    propertyInfo.SetValue(obj, Convert.ChangeType(row[prop.Name], propertyInfo.PropertyType), null);
}
 
Share this answer
 
try this code,
i am using this for long time.

C#
public static List<T> DataTableToList<T>(DataTable dt) where T : class, new()
{
    List<T> lstItems = new List<T>();
    if (dt != null && dt.Rows.Count > 0)
        foreach (DataRow row in dt.Rows)
            lstItems.Add(ConvertDataRowToGenericType<T>(row));
    else
        lstItems = null;
    return lstItems;
}

private static T ConvertDataRowToGenericType<T>(DataRow row) where T : class,new()
{
    Type entityType = typeof(T);
    T objEntity = new T();
    foreach (DataColumn column in row.Table.Columns)
    {
        object value = row[column.ColumnName];
        if (value == DBNull.Value) value = null;
        PropertyInfo property = entityType.GetProperty(column.ColumnName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public);
        try
        {
            if (property != null && property.CanWrite)
                property.SetValue(objEntity, value, null);

        }
        catch (Exception ex)
        {
           throw ex;
        }
    }
    return objEntity;
}
 
Share this answer
 
Comments
Philippe Mori 22-Aug-16 18:59pm    
Catching an exception to rethrow it by value does not make much sense. It is a poor coding practice.
Karthik_Mahalingam 23-Aug-16 0:52am    
agree,

this was my original code.

catch (Exception ex)
{
string exceptionMessageInfo_Names = string.Format("SQL Column Name:= {0} \n BusinessType Property Name:= {1}", column.ColumnName, property != null ? property.Name : string.Empty);
string exceptionMessageInfo_DataTypes = string.Format("SQL Column Type:= {0} \n BusinessType Property Type:= {1}", column.DataType, property != null ? property.PropertyType.Name : string.Empty);
throw new Exception("Error Message := " + ex.Message + Environment.NewLine + exceptionMessageInfo_Names +
Environment.NewLine + exceptionMessageInfo_DataTypes);
}
Philippe Mori 23-Aug-16 8:12am    
Then why not using the constructor with an inner exception: Exception Constructor (String, Exception)?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900