Search code examples
c#datatableblueprism

C# - DataTable within a DataTable


In Blue Prism (BP), there is something called a Collection, which is basically a DataTable in C#. In BP, you can have a Collection within a Collection. My question is, can you have a DataTable within a DataTable in C#?

Here is my code below:

//inner datatable
DataTable dt2 = new DataTable();
DataColumn dc5 = new DataColumn("TestOne");
DataColumn dc6 = new DataColumn("TestTwo");
dt2.Columns.Add(dc5);
dt2.Columns.Add(dc6);
dt2.Rows.Add("Value1", "Value2");

//outer datatable
DataTable dt = new DataTable();
DataColumn dc1 = new DataColumn("Name");
DataColumn dc2 = new DataColumn("Age");
DataColumn dc3 = new DataColumn("Gender");
DataColumn dc4 = new DataColumn("InnerDataTable");
dt.Columns.Add(dc1);
dt.Columns.Add(dc2);
dt.Columns.Add(dc3);
dt.Columns.Add(dc4);

//adding of inner datatable to outer datatable
dt.Rows.Add("John", "23", "Male", dt2);
dt.Rows.Add("Gretchen", "25", "Female", dt2);
dt.Rows.Add("Jordan", "28", "Male", dt2);

DataSet ds = new DataSet();
ds.Tables.Add(dt);
string xml = ds.GetXml();
Console.WriteLine(xml);
Console.ReadLine();

At the end, I am parsing the DataSet into an XML but the InnerDataTable column does not have any value. Is there something I am doing wrong here or is this simply not possible in C#?

This is the output I want in Console:

<NewDataSet>
  <Table1>
    <Name>John</Name>
    <Age>23</Age>
    <Gender>Male</Gender>
    <InnerDataTable>
      <TestOne>Value1</TestOne>
      <TestTwo>Value2</TestTwo>
    </InnerDataTable>
  </Table1>
  <Table1>
    <Name>Gretchen</Name>
    <Age>25</Age>
    <Gender>Female</Gender>
    <InnerDataTable>
      <TestOne>Value1<TestOne>
      <TestTwo>Value2</TestTwo>
    </InnerDataTable>
  </Table1>
  <Table1>
    <Name>Jordan</Name>
    <Age>28</Age>
    <Gender>Male</Gender>
    <InnerDataTable>
      <TestOne>Value1<TestOne>
      <TestTwo>Value2</TestTwo>
    </InnerDataTable>
  </Table1>
</NewDataSet>

But this is what is actually shown:

<NewDataSet>
  <Table1>
    <Name>John</Name>
    <Age>23</Age>
    <Gender>Male</Gender>
    <InnerDataTable />
  </Table1>
  <Table1>
    <Name>Gretchen</Name>
    <Age>25</Age>
    <Gender>Female</Gender>
    <InnerDataTable />
  </Table1>
  <Table1>
    <Name>Jordan</Name>
    <Age>28</Age>
    <Gender>Male</Gender>
    <InnerDataTable />
  </Table1>
</NewDataSet>

Solution

  • The problem lies within your code that defines the schema of the DataTable, specifically where you define the column for InnerDataTable.

    DataColumn dc4 = new DataColumn("InnerDataTable");
    

    The constructor initializes the instance of DataColumn class, as type string. If you want the type to be DataTable, then you want the type to be of typeof(DataTable).

    DataColumn dc4 = new DataColumn("InnerDataTable", typeof(DataTable));
    

    However, defining InnerDataTable as a DataTable type will not get the output you are expecting. You will need to define a class to model the InnerDataTable.

    public class InnerTable
    {
        public string TestOne { get; set; }
        public string TestTwo { get; set; }
    }
    

    And then define InnerDataTable column of typeof(InnerTable).

    DataColumn dc4 = new DataColumn("InnerDataTable", typeof(InnerTable));
    

    I have put up the full solution at dotnetfiddle.