.net 从平面数据库结果集填充对象层次结构的最佳实践?

.net 从平面数据库结果集填充对象层次结构的最佳实践?,.net,data-structures,.net,Data Structures,这是从平面列表生成树时经常出现的问题。我发现自己依赖于下面描述的两级方法。 我希望有人能提出一个更好的方法,可以很容易地扩展到多个层面 说明: Resultset是平面的,包含对parentId的引用 根项的parentId为null或零。在示例中,FromDb.ParseInt代码将通过将DBNull转换为零来处理它 使用(SqlDataReader=command.ExecuteReader()) { 列表结果=新列表(); ParentDataObject parent=新的Pare

这是从平面列表生成树时经常出现的问题。我发现自己依赖于下面描述的两级方法。 我希望有人能提出一个更好的方法,可以很容易地扩展到多个层面

说明:

  • Resultset是平面的,包含对parentId的引用
  • 根项的parentId为null或零。在示例中,FromDb.ParseInt代码将通过将DBNull转换为零来处理它

使用(SqlDataReader=command.ExecuteReader())
{
列表结果=新列表();
ParentDataObject parent=新的ParentDataObject();
ParentDataObject previousParent=null;
while(reader.Read())
{
parent.Id=FromDb.ParseInt(读取器[“ParentId”]);
//父级 if(previousParent==null | | parent.Id!=previousParent.Id) { if(previousParent!=null) { results.Add(previousParent);//保存以前处理过的ParentDataObject } 父对象=新的ParentDataObject(); //用数据填充父对象。。。 } //子级 ChildDataObject child=新的ChildDataObject; //用数据填充子项。。。 parent.Children.Add(child); previousParentId=currentParentId; } //将最后一个父项添加到结果 if(previousParent!=null) 结果:添加(以前的父项); }

像这样的东西怎么样?(伪代码)

类层次结构对象
{
int-ID;
列出儿童名单;
//其他领域
}
...
变量根=新列表();
var index=newdictionary();
while(reader.Read())
{
HierarchicalObject当前=新的HierarchicalObject();
//从记录中填写数据
int parentID=(int)读取器[“parentID”];
if(parentID!=0)
{
索引[parentID]。Children.Add(当前);
}
其他的
{
根。添加(当前);
}
index.Add(current.ID,current);
}
//根现在包含根对象列表;丢弃指数
这假设您的所有对象都是同质的,而不是具有单独的父/子类,并且顺序是这样的,即在读取子对象的父对象之前,不会先读取子对象。。。但它应该适用于多个级别,您可以根据需要进行调整

(如果第二个假设不成立,您可以先将所有记录读入索引,然后返回索引并修复根和子项。)


using (SqlDataReader reader = command.ExecuteReader())
{
    List<ParentDataObject> results = new List<ParentDataObject>();
    ParentDataObject parent = new ParentDataObject();
    ParentDataObject previousParent = null;
    while (reader.Read())
    {
        parent.Id = FromDb.ParseInt(reader["ParentId"]);
// Parent-level if (previousParent == null || parent.Id != previousParent.Id) { if (previousParent != null) { results.Add(previousParent); // save previously processed ParentDataObject } parent = new ParentDataObject(); // Fill parent object with data... } // Child-level ChildDataObject child = new ChildDataObject; // Fill child with data... parent.Children.Add(child); previousParentId = currentParentId; } // add last parent to results if (previousParent != null) results.Add(previousParent); }
class HierarchicalObject
{
    int ID;
    List<HierarchicalObject> Children;
    // Other fields
}

...

var roots = new List<HierarchicalObject>();
var index = new Dictionary<int, HierarchicalObject>();

while (reader.Read())
{
    HierarchicalObject current = new HierarchicalObject();

    // fill in data from record

    int parentID = (int)reader["ParentID"];

    if (parentID != 0)
    {
        index[parentID].Children.Add(current);
    }
    else
    {
        roots.Add(current);
    }

    index.Add(current.ID, current);   
}

// roots now contains list of root objects; throw out index