使用linq获取子项

时间:2018-12-31 16:30:09

标签: c# linq

我有类别和子类别,并且在存储过程中返回数据,如:

  SELECT
                 [RC].[Name] AS 'CategoryName'
                , [RS].[Name] AS 'SubcategoryName'
                 FROM [RedMarkCategory] AS [RC]
                     INNER JOIN [RedMarkSubcategory] AS [RS] ON [RC].[RedMarkCategoryId] = [RS].[RedMarkCategoryId]
                     WHERE RS.IsDeleted = 0
            ORDER BY
                   [RC].[Name]

输出:

enter image description here

如您所见,一个类别可以有多个子类别。

因此,在c#中,我首先获得要动态创建的类别GroupBoxes,并且要在GroupBox内为每个子类别创建Checkboxes

DataTable dataFromDb = GetData();

            string[] distinctCetgories = dataFromDb.AsEnumerable()
        .Select(x => x.Field<string>("CategoryName")).Distinct().ToArray();




foreach (var itm in distinctCetgories)
        {
            // extract all the subcategories for the checkboxes inside the groupbox
            string[] subcategories = dataFromDb.AsEnumerable().
                Where(x => x.Field<string>("SubcategoryName") == itm).
                Select(y => y.Field<string>("SubcategoryName")).ToArray();

            flpRedMarks.Controls.Add(GetGroupBox(itm, subcategories, 200, 100));
        }

类别创建成功,但子类别查询始终为0:

string[] subcategories = dataFromDb.AsEnumerable().
                    Where(x => x.Field<string>("SubcategoryName") == itm).
                    Select(y => y.Field<string>("SubcategoryName")).ToArray();

所以我总是得到空的复选框:

enter image description here

我的查询出了什么问题?问候

2 个答案:

答案 0 :(得分:4)

我相信在这里您想根据类别名称过滤子类别。但是相反,您的where子句正在与SubcategoryName

进行比较

所以不是

string[] subcategories = dataFromDb.AsEnumerable().
                Where(x => x.Field<string>("SubcategoryName") == itm).
                Select(y => y.Field<string>("SubcategoryName")).ToArray();

实际上应该是

 string[] subcategories = dataFromDb.AsEnumerable().
                Where(x => x.Field<string>("CategoryName") == itm).
                Select(y => y.Field<string>("SubcategoryName")).ToArray();

答案 1 :(得分:0)

作为替代方案,按CategoryName分组,然后为每个分组获得子类别。

这样一来,一切都可以完成。

例如

var categories = dataFromDb.AsEnumerable()
    .GroupBy(_ => _.Field<string>("CategoryName"))
    .Select(g => new {
        CategoryName = g.Key,
        SubCategories = g.Select(_ => _.Field<string>("SubcategoryName"))
    });


foreach (var category in categories) {
    var name = category.CategoryName;

    //...Create GroupBox
    var groupBox = new GroupBox() {
        Text = name
    };

    //...

    foreach (var subcategoryName in category.SubCategories) {

        //...Create CheckBbox with subcategoryName and add to groupbox

        var checkBox = new CheckBox();
        checkBox.Text = subcategoryName;

        //...

        groupBox.Controls.Add(checkBox);
    }

    //...do something with groupbox
}