Home > Software engineering >  Generic Method to convert datatable to list
Generic Method to convert datatable to list

Time:10-04

I'm using below code:

 public static List<T> ConvertToList1<T>(DataTable dt)
        {
            var columnNames = dt.Columns.Cast<DataColumn>()
                    .Select(c => c.ColumnName)
                    .ToList();
            var properties = typeof(T).GetProperties();
            return dt.AsEnumerable().Select(row =>
            {
                T objT1 = 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 objT1;
            }).ToList();
        }

But I'm getting error for decimal field having null values.

Invalid cast from 'System.Decimal' to 'System.Nullable`1[[System.Decimal, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral

 public class SampleModel
    {
        public Guid Id { get; set; }
        public Guid ProjectId { get; set; }
        public string? Code { get; set; } = null!;
        public string? Description { get; set; }
        public decimal? Quantity1 { get; set; }
        public decimal? Quantity2 { get; set; }
    }

Can anyone suggest how to fix this?

CodePudding user response:

Um, reading again... You mean that a non-null decimal value in the row cannot be assigned to a nullable decimal? Or did you mean a dbnull that cannot be assigned to the nullable decimal?


You can use the DataRow.IsNull to check if the value is dbnull. In that case you just skip it as the nullable already has default null.

// <CODE SNIP />

if (columnNames.Contains(pro.Name))
{
    // if the value was null, just skip it.
    if(!row.IsNull(pro.Name))
    {
        PropertyInfo? pI = objT.GetType().GetProperty(pro.Name);
        pro.SetValue(objT, Convert.ChangeType(row[pro.Name], pI.PropertyType));
    }
}

CodePudding user response:

Try following :

       public static List<SampleModel> ConvertToList1<T>(DataTable dt)
        {
            List<SampleModel> results = dt.AsEnumerable().Select(x => new SampleModel()
            {
                Id = x.Field<Guid>("Id"),
                ProjectId = x.Field<Guid>("ProjectId"),
                Code = x.Field<string>("Code"),
                Description = x.Field<string>("Description"),
                Quantity1 = x.Field<decimal>("Quantity1"),
                Quantity2 = x.Field<decimal>("Quantity1")
            }).ToList();


            return results;
        }
  • Related