在多个linq Where子句中使用相同的查找值,而不会查找多次

时间:2018-03-17 12:10:18

标签: c# linq

我有一个LINQ查询,它有三个Where子句。在每个Where子句中,我正在查找同一组项目以便比较值:

var items = _umbracoHelper.GetPage(ItemsPage.ModelTypeAlias).Children
                .Where(x => level1Category == 0 || x
                                .GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
                                .Select(y => y.Id).Contains(level1Category))
                .Where(x => !level2Categories.Any() || x
                                .GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
                                .Select(y => y.Id).Intersect(level2Categories.AsEnumerable()).Any())
                .Where(x => !level3Categories.Any() || x
                                .GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
                                .Select(y => y.Id).Intersect(level3Categories.AsEnumerable()).Any());

有没有办法可以获取UmbracoAlias.Items.Categories的值一次,并将该值存储在其他where子句中,而不会导致GetPropertyValue方法执行多次?

1 个答案:

答案 0 :(得分:2)

您可以将每个项目与类别ID配对,如下所示:

var items = _umbracoHelper.GetPage(ItemsPage.ModelTypeAlias).Children
    .Select(c => new {
        Child = c
    ,   CategoryIds = c
           .GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
           .Select(y => y.Id)
           .ToList()
    })
    .Where(x => level1Category == 0     || x.CategoryIds.Contains(level1Category))
    .Where(x => !level2Categories.Any() || x.CategoryIds.Intersect(level2Categories.AsEnumerable()).Any())
    .Where(x => !level3Categories.Any() || x.CategoryIds.Intersect(level3Categories.AsEnumerable()).Any())
    .Select(x => x.Child);

这会对子项目的过滤与其类别ID进行配对,然后仅在最终投影中保留Child个对象。

您可以通过合并所有三个Where子句来进一步简化:

var items = _umbracoHelper.GetPage(ItemsPage.ModelTypeAlias).Children
    .Where(c => {
        var categoryIds = c
           .GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
           .Select(y => y.Id)
           .ToList();
        if (level1Category != 0 && !categoryIds.Contains(level1Category)) {
            return false;
        }
        if (level2Categories.Any() && !categoryIds.Intersect(level2Categories.AsEnumerable()).Any()) {
            return false;
        }
        if (level3Categories.Any() && !categoryIds.Intersect(level3Categories.AsEnumerable()).Any()) {
            return false;
        }
        return true;
    });