LINQ Querying Collection с различными параметрами - PullRequest
0 голосов
/ 23 августа 2011

У меня есть список, который мне нужно запросить на основе примерно 10 различных параметров, которые пользователь передает в мою программу.

Какой лучший способ сделать это?

Например:

List<Users>   

Параметрами запроса могут быть: имя пользователя и / или идентификатор пользователя и / или возраст и т. Д.

Ответы [ 4 ]

0 голосов
/ 23 августа 2011

То, что вы пытаетесь достичь, это составление динамического запроса в LINQ. Вы можете сделать это двумя способами:

Вкратце, как использовать PredicateBuilder в вашем случае:

var predicate = PredicateBuilder.True<User>();
if (!string.IsNullOrWhitespace(username))
    predicate = predicate.And(a => a.Username == username);
if (!string.IsNullOrWhitespace(whatever))
    predicate = predicate.And(a => a.Whatever == whatever);
/* etc. etc. */

var filteredUsers = myUsers.Where(predicate);
0 голосов
/ 23 августа 2011

Полагаю, вы говорите о фильтрации объектов на основе первоначально неизвестного числа условий.

LINQ не оценивает ваш запрос, пока вы явно не зададите его, перечислив его (используя foreach, ToList (), ToArray () ...). И когда вы это сделаете, в зависимости от реализации LINQ (SQL, объекты, XML и т. Д.), Запрос будет оптимизирован.

AFAIK, все реализации способны оптимизировать «где условие1, где условие2» в «где условие1 && условие2».

Это означает, что вы просто должны добавить свои условия фильтрации по одному. Например:

private List<User> FilterUsers(string username, string userid, int? minAge, int? maxAge)
{
    IEnumerable<User> query = GetUsers();
    if (!string.IsNullOrEmpty(username)) query = query.Where(u => u.Username.StartsWith(username);
    if (!string.IsNullOrEmpty(userid)) query = query.Where(u => u.Userid == userid);
    if (minAge != null) query = query.Where(u => u.Age >= minAge.Value);
    if (maxAge != null) query = query.Where(u => u.Age <= maxAge.Value);

    return query.ToList();
}

Здесь GetUsers () должен возвращать IEnumerable. Может быть таблицей, если вы используете LINQ-to-SQL, ChildNodes (), если вы используете LINQ-to-XML. Попробуйте перечислить как можно меньше до применения ваших предложений where.

0 голосов
/ 23 августа 2011

То, что вы хотите сделать, - это иметь метод с следующей подписью

    public void Filter(Func<Account, bool> filterExpression)
    {
        list.Where(filterExpression).ToList();
    }

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

Не нарушая инкапсуляцию вашего (я полагаю) хранилища, поэтому я делаю ToList(), поэтому IQueryable не отправляется клиенту.

0 голосов
/ 23 августа 2011

Я предполагаю, что вы хотите динамически построить часть where вашего запроса Linq - я не рекомендую делать это через строку (см. Ссылку ниже), потому что это может привести к чему-то похожему на то, что известно как SQL-инъекция в LINQ.то есть изменение поведения запроса LINQ с предоставленными пользователем параметрами такими способами, которые вам не нужны ...

При этом проверьте эту ссылку http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx - Скотт Гу демонстрирует что-то, что близко кчто вы описываете, включая библиотеку и пример кода ...

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