Есть ли лучший способ написать функцию LINQ? - PullRequest
0 голосов
/ 16 февраля 2019

Итак, я новичок в LINQ и пытаюсь понять, как фильтровать элементы.Это моя задача

public async Task<PagedList<Item>> GetItems (ItemParams itemParams) {
    var items = _context.Items.AsQueryable ();
    if (itemParams.CategoryId > 0) {
        var category = GetCategory (itemParams.CategoryId);

        items = items.Where (i => FilterItems (i, category.Result));

    }
    return await PagedList<Item>.CreatAsync (items, itemParams.PageNumber, itemParams.PageSize);
}

и функция, которая решает, какие элементы возвращать, это

static bool FilterItems (Item item, Category category) {

    if (item.CategoryId == category.Id) {
        return true;
    }
    if (category.Children.Count > 0) {
        foreach (Category cat in category.Children) {
          return  FilterItems (item, cat);
        }
    }
    return false;
}

функция get getc

    public async Task<Category> GetCategory (int? id) {
        if (id == null) {
            return null;
        }
        var categories = _context.Categories.Include (x => x.Children).AsEnumerable ().Where (c => c.Id == id);
        categories = Traverse (categories);
        var category = await Task.FromResult (categories.First (c => c.Id == id));
        return category;
    }

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Из кода кажется, что FilterItems() возвращает true, если элемент находится в текущей категории или каких-либо подкатегориях?

Если это так, я думаю, что ваш текущий код имеет проблему: рекурсивный вызов FilterItems() немедленно возвращает результат для первой подкатегории без проверки других подкатегорий

Здесьизмененный код:

public static bool InCategoryOrSubCategory(Item item, Category category)
{
    return item.CategoryId == category.Id ||
        category.Children.Any(subCategory => InCategoryOrSubCategory(item, subCategory));
}

Я изменяю имя на InCategoryOrSubCategory, чтобы сделать его более понятным

Вот версия с карри, чтобы сделать вызов Where немного приятнее (но сам методнемного более загадочно):

public static Func<Item, bool> InCategoryOrSubCategory(Category category) 
{
    return item => 
        item.CategoryId == category.Id || 
        category.Children.Any(subCategory => InCategoryOrSubCategory(subCategory)(item));
}

Использование:

items.Where(InCategoryOrSubCategory(category))
0 голосов
/ 16 февраля 2019

Ваш фильтр не будет работать должным образом, так как foreach возвращается в первом цикле.Также имя FilterItems не является интуитивно понятным.

static bool ContainsItem(Category category, Item item)
{
    return
        category.Id == item.CategoryId ||
        category.Children.Any(c => ContainsItem(c, item);
}

Поскольку C # выполняет оценку короткого замыкания ||Оператор , второй член не будет оцениваться, если первый совпадает.Обратите внимание, что это не грязная уловка, а часть спецификации C #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...