Передача функций фильтрации в Where () в LINQ-to-SQL - PullRequest
1 голос
/ 28 апреля 2010

Я пытаюсь написать набор функций фильтрации, которые можно объединить в цепочку для постепенной фильтрации набора данных. Хитрость в том, что я хочу иметь возможность определять фильтры в другом контексте, нежели тот, в котором они будут использоваться. Я дошел до того, что смог передать очень базовую функцию предложению Where () в операторе LINQ:

файл фильтров:

Func<item, bool> returnTrue = (i) => true;

файл репозитория:

public IQueryable<item> getItems()
{
    return DataContext.Items.Where(returnTrue);
}

Это работает. Однако, как только я пытаюсь использовать более сложную логику, начинается проблема:

файл фильтров:

Func<item, bool> isAssignedToUser = (i) => i.assignedUserId == userId;

файл репозитория:

public IQueryable<item> getItemsAssignedToUser(int userId)
{
    return DataContext.Items.Where(isAssignedToUser);
}

Это даже не будет построено, потому что userId не находится в той же области, что и isAssignedToUser (). Я также попытался объявить функцию, которая принимает userId в качестве параметра:

Func<item, int, bool> isAssignedToUser = (i, userId) => i.assignedUserId == userId;

Проблема в том, что она не соответствует сигнатуре функции, которую ожидает Where ():

Func<item, bool>

Должен быть способ сделать это, но я не знаю, как это сделать. Я не чувствую, что объясняю это очень хорошо, но, надеюсь, вы понимаете суть.

Спасибо

Daniel

Ответы [ 2 ]

0 голосов
/ 28 апреля 2010

Благодаря чудесам замыканий userId уже находится в области действия, если вы используете встроенную анонимную функцию в предложении Where. Это означает, что когда у вас есть анонимная функция в методе, переменные в методе доступны анонимной функции, даже если они кажутся «внешними».

public IQueryable<item> getItemsAssignedToUser(int userId)
{
    return DataContext.Items.Where( i => i.assignedUserId == userId);
}

Вы также могли бы создать Func isAssignedToUser внутри метода getItemsAssignedToUser и передать его в предложение Where, как это, но в этом нет необходимости:

public IQueryable<item> getItemsAssignedToUser(int userId)
{
    Func<item, bool> isAssignedToUser = (i) => 
    {
        return i.assignedUserId == userId; 
    };

    return DataContext.Items.Where(isAssignedToUser);
}
0 голосов
/ 28 апреля 2010

Вам не нужно объявлять свои функции как чисто автономные функции.Вы можете использовать встроенную лямбду:

public IQueryable<item> getItemsAssignedToUser(int userId)
{
    return DataContext.Items.Where(i => i.assignedUserId == userId);
}

Официальная документация для лямбды здесь на MSDN , но вы можете найти более удобный для чтения поиск в Google.

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