sql >> Databasteknik >  >> RDS >> Mysql

Plattare barn-/förälderdata med okänt antal kolumner

Efter många dagars arbete med detta har jag lyckats lösa problemet själv. Det jag gjorde var följande;

I min ursprungliga barnklass gör MemberCode och ElementCode en unik nyckel som i princip angav vad kolumnnamnet var. Så jag tog det här ett steg längre och la till ett "Column_Name" så att jag hade

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; }
}

Detta återspeglades uppenbarligen i min databastabell också.

Min SQL för att extrahera data såg sedan ut så här;

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

beställning av UniqueID först är avgörande för att säkerställa att posterna är i rätt ordning för senare bearbetning.

Jag skulle använda en dynamic och en ExpandoObject() för att lagra data.

Så jag itererar över resultatet för att konvertera SQL-resultatet till denna struktur enligt följande;

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

Sedan har jag min information lagrad dynamiskt på det platta sätt som jag behövde.

Nu var nästa problem ObjectListView jag ville använda. Detta kunde inte acceptera sådana dynamiska typer.

Så jag hade informationen lagrad i min kod som jag ville, men jag kunde fortfarande inte visa den som krävdes.

Lösningen var att använda en variant av ObjectListView känd som DataListView . Detta är i praktiken samma kontroll men kan vara databunden. Ett annat alternativ skulle också vara att använda en DatagridView, men jag ville hålla mig till ObjectListView av andra skäl.

Så nu var jag tvungen att konvertera min dynamiska data till en datakälla. Detta gjorde jag enligt följande;

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);
}

Sedan tilldelar jag helt enkelt min datakälla till DataListView, genererar kolumnerna, och hej då har jag nu min dynamiska data extraherad, tillplattad och visad hur jag behöver.




  1. Databasdesign för att lagra chattmeddelanden mellan människor

  2. Londiste-replikering med PostgreSQL 9.0

  3. Mysql int(11) nummer utanför intervallet

  4. Vilken är den lämpligaste datatypen för att lagra en IP-adress i SQL-servern?