我在数据库中有一个表格,如下所示;
ID P_ID ATTRIBUTE PARENT_ID SEQUENCE
----------------------------------------------------
1 1 INDIVIDUAL // return the list contains same P_ID with no PARENT_ID,
2 1 FIRST_NAME 1 1 // element of parent INDIVIDUAL
3 1 SECOND_NAME 1 2
4 1 INDIVIDUAL_ALIAS 1 3
5 1 ALIAS_NAME 4 1 // element of INDIVIDUAL/INDIVIDUAL_ALIAS
6 1 DOCUMENTS 1 4
7 1 NATIONAL_IDs 6 1
8 1 ID 7 1 //element of INDIVIDUAL/DOCUMENTS/NATIONAL_IDs
9 1 Passport 7 2
10 1 SSN 7 3
11 2 sdnEntry // new parent entry
12 2 firstName 11 1
13 2 lastName 11 2
14 2 aka 11
15 2 firstName 14 1
16 2 lastName 14 2
17 1 ENTITY // second list member of P_ID == 1
18 1 FIRST_NAME 17 1
19 1 ENTITY_ALIAS 17
20 1 ALIAS_NAME 19 1
为了更好地理解树将是这样的;
Set up the tree if data fetched with P_ID = 1
INDIVIDUAL
|-FIRST_NAME
|-SECOND_NAME
|-INDIVIDUAL_ALIAS // list of ALIAS_NAME
|-ALIAS_NAME
|-DOCUMENTS // list of NATIONAL_IDs
|-NATIONAL_IDs // further list of documents
|-ID
|Passport
|SSN // may some other entry contains list here too
ENTITY
|-FIRST_NAME
|-ENTITY_ALIAS
|-ALIAS_NAME
我的映射数据类;如果有人建议在树增长时不需要更多表,那将非常感激,因为如果我增加树的级别,则需要为此创建类。
public class Attribute
{
public int ProcessId { get; set; }
public List<ParentAttribute> ParentNodes { get; set; }
}
public class ParentAttribute
{
public int id { get; set; }
public string parentNodeValue { get; set; }
public List<ChildAttribute> ChildNodeValues { get; set; }
}
public class ChildAttribute
{
public int? sequence { get; set; }
public string childNodeValue { get; set; } //can be only string OR List<ChildAttribute>
//public dynamic childNodeValue { get; set; } //unable to work with dynamic and object
public int? parentId { get; set; }
}
//I was thinking to add table if tree level goes further up, but this is not good approach
public class GrandChildAttribute
{
public int sequence { get; set; }
public string grandChildNodeValue { get; set; }
public int parentId { get; set; }
}
this is how I am trying to map data in my C# code, Which is also not good way, I need to add another foeeach loop if data needs to be taken from further list.
public static Attribute GetProcessAttributes()
{
using (OracleConnection oCon = new OracleConnection(Con))
{
Attribute att = new Attribute();
string query = @"SELECT * from Process where Process_Id = :Process_Id";
OracleCommand cmd = new OracleCommand(query, oCon);
cmd.Parameters.AddWithValue("Process_Id", 1);
oCon.Open();
OracleDataReader rdr = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(rdr);
if (dt.Rows.Count > 0)
{
foreach (DataRow row in dt.Rows)
{
att.ProcessId = Convert.ToInt32(row["Process_Id"]);
att.ParentNodes = new List<ParentAttribute>();
var pNodes = (from pRow in dt.AsEnumerable()
where pRow.Field<decimal?>("Parent_Id") == null
select pRow).ToList();
foreach (var pItem in pNodes)
{
ParentAttribute pAtt = new ParentAttribute();
pAtt.parentNodeValue = pItem["Attribute"].ToString();
pAtt.id = Convert.ToInt32(pItem["ID"]);
pAtt.ChildNodeValues = new List<ChildAttribute>();
var cNodes = (from cRow in dt.AsEnumerable()
where cRow.Field<decimal?>("Parent_Id") == pAtt.id
select cRow).ToList();
foreach (var cItem in cNodes)
{
int currentId = Convert.ToInt32(cItem["ID"]);
var gNodes = (from gRow in dt.AsEnumerable()
where gRow.Field<decimal?>("Parent_Id") == currentId
select gRow).ToList();
ChildAttribute cAtt = new ChildAttribute();
if (gNodes.Count > 0)
{
cAtt.childNodeValue = new List<ChildAttribute>();
cAtt.sequence = Convert.ToInt32(!cItem.IsNull("Sequence"));
cAtt.parentId = Convert.ToInt32(!cItem.IsNull("Parent_Id"));
ChildAttribute gAtt = new ChildAttribute();
//unable to add this list to its parent
foreach (var gItem in gNodes)
{
gAtt.childNodeValue = new ChildAttribute()
{
childNodeValue = cItem["Attribute"].ToString(),
sequence = Convert.ToInt32(!cItem.IsNull("Sequence")),
parentId = Convert.ToInt32(!cItem.IsNull("Parent_Id"))
};
(cAtt.childNodeValue as List<ChildAttribute>).Add(gAtt);
}
}
else
{
cAtt.childNodeValue = cItem["Attribute"].ToString();
cAtt.sequence = Convert.ToInt32(!cItem.IsNull("Sequence"));
cAtt.parentId = Convert.ToInt32(!cItem.IsNull("Parent_Id"));
pAtt.ChildNodeValues.Add(cAtt);
}
}
att.ParentNodes.Add(pAtt);
}
}
}
return att;
}
}
关于我的要求的任何其他建议也将不胜感激。我需要将树中显示的数据提取到我的对象类中以进一步解决它们。我也无法获取INDIVIDUAL_ALIAS
列表的数据,因为FIRST_NAME
和SECOND_NAME
是字符串类型,INDIVIDUAL_ALIAS
是列表类型。