Setelah beberapa hari mengerjakan ini maka saya telah berhasil menyelesaikan masalah ini sendiri. Apa yang saya lakukan adalah sebagai berikut;
Di kelas anak asli saya, MemberCode dan ElementCode membuat kunci unik yang pada dasarnya menyatakan apa nama kolom itu. Jadi saya mengambil langkah lebih jauh dan menambahkan "Column_Name" sehingga saya memiliki
public class Child
{
public int MemberCode { get; set; } //Composite key
public int ElementCode { get; set; } //Composite key
public string Column_Name { get; set; } //Unique. Alternative Key
public Object Data { get; set; }
}
Ini jelas tercermin dalam tabel database saya juga.
SQL saya untuk mengekstrak data kemudian terlihat seperti ini;
select p.UniqueID, p.LoadTime, p.reference, c.MemberCode, c.ElementCode , c.column_name, c.Data
from parent as p, child as c
where p.UniqueID = c.UniqueID
//aditional filter criteria
ORDER BY p.UniqueID, MemberCode, ElementCode
memesan oleh UniqueID terlebih dahulu sangat penting untuk memastikan catatan berada dalam urutan yang benar untuk diproses nanti.
Saya akan menggunakan dynamic
dan ExpandoObject()
untuk menyimpan data.
Jadi saya mengulangi hasilnya untuk mengonversi hasil sql ke dalam struktur ini sebagai berikut;
List<dynamic> allRecords = new List<dynamic>(); //A list of all my records
List<dynamic> singleRecord = null; //A list representing just a single record
bool first = true; //Needed for execution of the first iteration only
int lastId = 0; //id of the last unique record
foreach (DataRow row in args.GetDataSet.Tables[0].Rows)
{
int newID = Convert.ToInt32(row["UniqueID"]); //get the current record unique id
if (newID != lastId) //If new record then get header/parent information
{
if (!first)
allRecords.Add(singleRecord); //store the last record
else
first = false;
//new object
singleRecord = new List<dynamic>();
//get parent information and store it
dynamic head = new ExpandoObject();
head.Column_name = "UniqueID";
head.UDS_Data = row["UniqueID"].ToString();
singleRecord.Add(head);
head = new ExpandoObject();
head.Column_name = "LoadTime";
head.UDS_Data = row["LoadTime"].ToString();
singleRecord.Add(head);
head = new ExpandoObject();
head.Column_name = "reference";
head.UDS_Data = row["reference"].ToString();
singleRecord.Add(head);
}
//get child information and store it. One row at a time
dynamic record = new ExpandoObject();
record.Column_name = row["column_name"].ToString();
record.UDS_Data = row["data"].ToString();
singleRecord.Add(record);
lastId = newID; //store the last id
}
allRecords.Add(singleRecord); //stores the last complete record
Kemudian saya menyimpan informasi saya secara dinamis dengan cara yang saya butuhkan.
Sekarang masalah berikutnya adalah ObjectListView yang ingin saya gunakan. Ini tidak dapat menerima tipe dinamis seperti itu.
Jadi saya memiliki informasi yang disimpan dalam kode saya seperti yang saya inginkan, tetapi saya masih tidak dapat menampilkannya seperti yang diperlukan.
Solusinya adalah menggunakan varian ObjectListView
dikenal sebagai DataListView
. Ini secara efektif merupakan kontrol yang sama tetapi dapat terikat data. Alternatif lain juga menggunakan DatagridView, tetapi saya ingin tetap menggunakan ObjectListView karena alasan lain.
Jadi sekarang saya harus mengubah data dinamis saya menjadi Sumber Data. Ini saya lakukan sebagai berikut;
DataTable dt = new DataTable();
foreach (dynamic record in allRecords)
{
DataRow dr = dt.NewRow();
foreach (dynamic item in record)
{
var prop = (IDictionary<String, Object>)item;
if (!dt.Columns.Contains(prop["Column_name"].ToString()))
{
dt.Columns.Add(new DataColumn(prop["Column_name"].ToString()));
}
dr[prop["Column_name"].ToString()] = prop["UDS_Data"];
}
dt.Rows.Add(dr);
}
Kemudian saya cukup menetapkan sumber data saya ke DataListView, membuat kolom, dan sekarang, data dinamis saya telah diekstraksi, diratakan, dan ditampilkan sesuai kebutuhan.