Подтвердить что ты не робот

Динамическое предложение where (OR) в Linq для объектов

В сообщении here я узнал, как построить динамический запрос, используя отложенное выполнение Linq. Но на самом деле запрос использует конкатенацию AND условия WHERE.

Как я могу достичь того же запроса, но с логикой ИЛИ?

В связи с перечислением Flags запрос должен искать имя пользователя, имя пользователя Windows или обоих:

public User GetUser(IdentifierType type, string identifier)
{
    using (var context = contextFactory.Invoke())
    {
        var query = from u in context.Users select u;

        if (type.HasFlag(IdentifierType.Username))
            query = query.Where(u => u.Username == identifier);

        if (type.HasFlag(IdentifierType.Windows))
            query = query.Where(u => u.WindowsUsername == identifier);

        return query.FirstOrDefault();
    }
}
4b9b3361

Ответ 1

С LINQKit PredicateBuilder вы можете строить предикаты динамически.

var query = from u in context.Users select u;
var pred = Predicate.False<User>();

if (type.HasFlag(IdentifierType.Username))
    pred = pred.Or(u => u.Username == identifier);

if (type.HasFlag(IdentifierType.Windows))
    pred = pred.Or((u => u.WindowsUsername == identifier);

return query.Where(pred.Expand()).FirstOrDefault();
// or return query.AsExpandable().Where(pred).FirstOrDefault();

Это то, что Expand для:

Конвейер обработки запросов Entity Framework не может обрабатывать вызовы, поэтому вам нужно вызвать AsExpandable для первого объекта в запросе. Вызывая AsExpandable, вы активируете класс посетителей выражения LINQKit, который заменяет выражения вызова более простыми конструкциями, которые может понять Entity Framework.

Или: без него выражение Invoke d, что вызывает исключение в EF:

В LINQ to Entities выражение LINQ node type 'Invoke' не поддерживается.

Позднее добавление:

Существует альтернативный построитель предикатов, который делает то же самое, но без Expand: http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/

Ответ 2

Это должно помочь.

Содержит запрос по нескольким столбцам

Похоже, что в дизайне таблицы есть фундаментальная проблема (пожалуйста, поправьте меня, если я ошибаюсь). Какова цель IdentifierType в вашей базе данных?