how to convert class object with nested array to datatable?

I need to convert class object to datatable. i have done it but there is a problem with array in the class object which is not populating in the datatable.

here is my code

public DataTable objToDataTable(RecomData obj)
        {
            DataTable dt = new DataTable("OutputData");

            DataRow dr = dt.NewRow();
            dt.Rows.Add(dr);

            obj.GetType().GetProperties().ToList().ForEach(f =>
            {
                try
                {
                    f.GetValue(obj, null);
                    dt.Columns.Add(f.Name, f.PropertyType);
                    dt.Rows[0][f.Name] = f.GetValue(obj, null);
                }
                catch { }
            });
            return dt;
        }

and here is the class

public class RecomData
    {

        public int UserID { get; set; }

        public string Gender { get; set; }
        public string DateTo { get; set; }
        public string DateFrom { get; set; }
        public string Relegion { get; set; }
        public string Age { get; set; }
        public string DailyHrs { get; set; }
        public string OtherServices { get; set; }
        public string Comments { get; set; }
        public string[] TasksArr { get; set; }
    }

}

this code is working but not populating TaskArr in datatablehere is the image

3 answers

  • answered 2018-01-14 11:17 Ian Robertson

    Your approach to your problem is not a popular way to do this.

    Most developers would use EntityFramework to declare entities, and abstract away from ADO.NET/DataTable/DataRow

    Your RecomData class could form the basis of an entity with no modification, you would just have to set up your DbContext to describe the tables (DbSet<RecomData> RecomData) in your Db and their relationships.

    All your CRUD operations would become very straight forward after this.

  • answered 2018-01-14 11:17 Levanan Gan

    suggest not to view through Dataset Visualizer.

    Should place breakpoint just after the class is converted to datatable and verify if the object value is inside.

    I think the value is valid and available, check .Rows[0]["TasksArr"].

  • answered 2018-01-14 11:17 jdweng

    Do you have one RecomData object or multiple. The code below assumes you have more than one RecomData :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                RecomData recomData = new RecomData();
                List<RecomData> data = new List<RecomData>();
                recomData.objToDataTable(data, true);
            }
        }
        public class RecomData
        {
    
            public int UserID { get; set; }
    
            public string Gender { get; set; }
            public DateTime DateTo { get; set; }
            public DateTime DateFrom { get; set; }
            public string Relegion { get; set; }
            public int Age { get; set; }
            public int DailyHrs { get; set; }
            public string OtherServices { get; set; }
            public string Comments { get; set; }
            public string[] TasksArr { get; set; }
    
            DataTable dt = null;
    
            public DataTable objToDataTable(List<RecomData> obj, Boolean createTable)
            {
                int maxTaskArr = obj.Max(x => x.TasksArr.Length);
    
                if (createTable)
                {
                    dt = new DataTable("OutputData");
                    DataRow dr = dt.NewRow();
    
                    dt.Columns.Add("Gender", typeof(string));
                    dt.Columns.Add("DateTo", typeof(DateTime));
                    dt.Columns.Add("DateFrom", typeof(DateTime));
                    dt.Columns.Add("Religion", typeof(string));
                    dt.Columns.Add("Age", typeof(int));
                    dt.Columns.Add("DailyHrs", typeof(int));
                    dt.Columns.Add("OtherServices", typeof(string));
                    dt.Columns.Add("Comments", typeof(string));
    
                    for (int i = 0; i < maxTaskArr; i++)
                    {
                        dt.Columns.Add("Task_" + i.ToString(), typeof(string));
                    }
                }
                else
                {
                    int numberTasks = dt.Columns.Cast<DataColumn>().Where(x => x.ColumnName.StartsWith("Task_")).Count();
                    for (int i = numberTasks; i < maxTaskArr; i++)
                    {
                        dt.Columns.Add("Task_" + i.ToString(), typeof(string));
                    }
                }
    
                foreach (RecomData recomData in obj)
                {
                    DataRow newRow = dt.Rows.Add();
    
                    newRow["Gender"] = recomData.Gender;
                    newRow["DateTo"] = recomData.DateTo;
                    newRow["DateFrom"] = recomData.DateFrom;
                    newRow["Religion"] = recomData.Relegion;
                    newRow["Age"] = recomData.Age;
                    newRow["DailyHrs"] = recomData.DailyHrs;
                    newRow["OtherServices"] = recomData.OtherServices;
    
                    int index = 0;
                    foreach (string task in recomData.TasksArr)
                    {
                        newRow["Task_" + index.ToString()] = task;
                    }
    
                }
                return dt;
            }
        }
    
    }