1

我有一个如下所示的 SQL 表:

orderID       customerName        orderDate          valueTotal
================================================================
   1             JohnA            01/02/2013            100
   2             AmandaF          01/02/2013            140
   3             JohnA            05/03/2013             58
   4             FredM            05/03/2013            200

我想根据用户设置在treeViewbyorderDate或上订购此信息customerName,这样如果按 customerName 订购,它看起来像这样:

JohnA
    01/02/2013
    05/03/2013
AmandaF
    01/02/2013
FredM
     05/03/2013

如果按 orderDate 排序,或者像这样:

01/02/2013
    JohnA
    AmandaF
05/03/2013
    JohnA
    FredM

实现这一目标的最佳方法是什么?

编辑: 我正在使用 Windows 窗体

4

2 回答 2

0

如果您使用的是 ADO.Net,请对此进行测试:

Dictionary<string, List<string>> groups = new Dictionary<string, List<string>>();

//set these dynamic
string groupingFieldName = "customerName";
string targetFieldName = "orderDate";


SqlDataReader rdr = sqlCmd.ExecuteReader();
while (rdr.Read())
{
    if (!groups.ContainsKey(rdr[groupingFieldName].ToString()))
    {
         groups.Add(rdr[groupingFieldName].ToString(), new List<string>());
    }
    groups[rdr[groupingFieldName].ToString()].Add(rdr[targetFieldName].ToString());
}

//next, iterate the dictionary and populate the treeView
foreach (KeyValuePair<string, List<string>> group in groups)
{
     //add to treeView
}

请注意,这未经测试。你仍然需要测试它。

于 2013-11-05T15:22:36.423 回答
0

我最终创建了两个函数来以更动态和可扩展的方式执行此操作。

    public static TreeNodeCollection SqlToTreeNodeHierarchy(this SqlDataReader dataReader, TreeNode parent)
    {
        // create a parent TreeNode if we don't have one, so we can anchor the new TreeNodes to it
        // I think this will work better than a list since we might be given a real parent..
        if (parent == null)
        {
            parent = new TreeNode("topNode");
        }

        while (dataReader.Read())
        {
            //at the beginning of each row, reset the parent
            var parentNode = parent;

            for (var i = 0; i < dataReader.FieldCount; i++)
            {
                // Adds a new TreeNode as a child of parentNode if it doesn't already exist
                // at this level, else it will return the existing TreeNode and save 
                // it onto parentNode. This way, subsequent TreeNodes will always be a child 
                // of this one, until a new row begins and the parent TreeNode is reset.
                parentNode = AddUniqueNode(dataReader[i].ToString(), parentNode);
            }
        }

        return parent.Nodes;
    }

    public static TreeNode AddUniqueNode(string text, TreeNode parentNode)
    {
        // if parentNode is null, create new treeNode and return it
        if (parentNode == null)
        {
            return new TreeNode {Name = text, Text = text};
        }

        // if parentNode is not null, do a find for child nodes at this level containing the key
        // we're after (text and name have the same value) and return the first one it finds
        foreach (var childNode in parentNode.Nodes.Find(text, false))
        {
            return childNode;
        }

        // Node does not yet exist, so just add a new node to the parentNode and return that
        return parentNode.Nodes.Add(text, text);
    }

然后我只需要如下调用函数:

using (var sqlConn = new SqlConnection(connectionString))
{
    sqlConn.Open();

    const string query = "SELECT orderDate, customerName from MAIN";

    using (var sqlCommand = new SqlCommand(query, sqlConn))
    {
        using (var sqlDataReader = sqlCommand.ExecuteReader())
        {
            var treeNodeCollection = sqlDataReader.SqlToTreeNodeHierarchy(null);

            foreach (TreeNode treeNode in treeNodeCollection)
            {
                nativeTreeView.Nodes.Add(treeNode);
            }
        }
    }
}

通过这种方式,我可以使用任意数量的子节点对其进行扩展,并且它还为我提供了仅在展开时加载子节点的灵活性,方法是执行另一个 SQL 查询并将父节点作为刚刚展开的 TreeNode 传递。

于 2013-11-06T10:56:34.730 回答