经过很多天的努力,我自己成功解决了这个问题。我所做的如下;
在我原来的子类中,MemberCode 和 ElementCode 生成一个唯一的键,基本上说明了列名是什么。所以我更进一步并添加了一个“Column_Name”,这样我就有了
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; }
}
这显然也反映在我的数据库表中。
我用来提取数据的 SQL 看起来像这样;
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
首先按 UniqueID 排序对于确保记录以正确的顺序供以后处理至关重要。
我会用一个dynamic
and a ExpandoObject()
来存储数据。
因此,我迭代结果,将 sql 结果转换为此结构,如下所示;
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
然后我以我需要的扁平方式动态存储我的信息。
现在下一个问题是我想使用的 ObjectListView。这不能接受这样的动态类型。
因此,我按照需要将信息存储在代码中,但仍然无法按要求显示它。
解决方案是使用ObjectListView
被称为DataListView
。这实际上是相同的控件,但可以进行数据绑定。
另一种选择也是使用 DatagridView,但由于其他原因我想坚持使用 ObjectListView。
所以现在我必须将动态数据转换为数据源。我这样做如下;
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);
}
然后,我只需将数据源分配给 DataListView,生成列,嘿,现在我已经提取、展平并显示了我需要的动态数据。