LINQ - listview - 一个表中的2个数据级别

时间:2012-10-04 20:26:05

标签: asp.net linq listview

我一直试图解决这个问题,我似乎无法弄明白。我不确定是不是因为我的db设计和LINQ,但我希望在这里有一些方向。

我的数据库表:

Id         Name         ParentId 
1          Data1        null 
2          Data2        null 
3          Data3        null 
4          Data4        1 
5          Data5        1 
6          Data6        2 
7          Data7        2 

基本上Data1和Data2是我想用于标题的最高级别,他们的孩子将根据他们的ParentID进行关联。

我正在尝试使用listview来显示如下数据:

Data1
-----
   Data4
   Data5

Data2
-----
   Data6
   Data7

我正在尝试使用LINQ和listview的组合来完成此任务。

以下是linq查询的代码:

var query = from data in mydb.datatable
where data.ParentId == null
select data;

但是这只给出了标题级别......不幸的是listview只占用了1个数据源。

3 个答案:

答案 0 :(得分:0)

虽然有些数据库(比如2005年的SQL Server)可以编写递归查询,但我不认为那些是由LINQ生成的。另一方面,如果记录数量足够小,您可以实现数据(到列表)并编写使用递归函数生成列表的LINQ查询。

这是来自内存,但它看起来像这样:

Func<int?,IEnumerable<data>> f = null;
f = parentId => {
    IEnumerable<data> result = from data in mydb.datatable
                               where data.ParentId = parentId
                               select data;
    return result.ToList().SelectMany(d=>f(d.Id));
};

那可以让你获得层次结构。

答案 1 :(得分:0)

如果您的层次结构只有两个级别,您可以使用组连接和匿名对象:

var query = from data in mydb.datatable.Where(x => x.ParentId == null)
            join child in mydb.datatable.Where(x => x.ParentId != null)
            on data.Id equals child.ParentId into children
            select new { data, children };

编辑:您必须将数据转换为可绑定到ListView的集合。一个黑客就是在子项目前面有一个只有一层深度的列表:

var listViewItems = (from item in query.AsEnumerable()
                     let dataName = item.data.Name
                     let childNames = item.children.Select(c => "    " + c.Name)
                     from name in dataName.Concat(childNames)
                     select new ListViewItem(name)).ToArray();

您还可以尝试找到更适合的控件,例如TreeView。您可能想要就此问题提出单独的问题。

答案 2 :(得分:0)

我刚刚写了一篇博文,描述了一个解决方案,用于构建一个自引用表的图形,该表具有单个LINQ查询,可能对数据库有用。请参阅http://www.thinqlinq.com/Post.aspx/Title/Hierarchical-Trees-from-Flat-Tables-using-LINQ