Условно где с или критериями linqtosql - PullRequest
1 голос
/ 17 декабря 2009

Я выяснил, как выполнять условные запросы с помощью linq to sql, а также выяснил, как использовать оператор OR where. К сожалению, я не могу понять, как сделать оба сразу. Я могу сделать условное предложение где-то вроде:

var ResultsFromProfiles = from AllPeeps in SearchDC.aspnet_Users
                          select AllPeeps;


if (SearchFirstNameBox.Checked)
{
    ResultsFromProfiles = ResultsFromProfiles.Where(p => p.tblUserProfile.FirstName.Contains(SearchTerm));
}

if (SearchLastNameBox.Checked)
{
    ResultsFromProfiles = ResultsFromProfiles.Where(p => p.tblUserProfile.LastName.Contains(SearchTerm));
}

Это даст мне любые профили, в которых имя И Фамилия содержат поисковый запрос.

Или я мог бы сделать:

var ResultsFromProfiles = from p in SearchDC.aspnet_Users
                          where p.tblUserProfile.LastName.Contains(SearchTerm) ||
                                p.tblUserProfile.FirstName.Contains(SearchTerm)
                          select p;

Это даст мне любые профили, где имя ИЛИ фамилия содержит поисковый запрос.

У меня есть несколько флажков, в которых пользователь может указать, какие поля он хочет найти для поискового запроса, поэтому я хочу иметь возможность создать запрос, который будет условно добавлять их, как в первом фрагменте кода выше, но добавить их как ИЛИ, поэтому они работают как второй фрагмент. Таким образом, он будет искать любые совпадения в любом месте указанных полей.

Какие-нибудь советы?

Ответы [ 3 ]

4 голосов
/ 17 декабря 2009

Да, используйте PredicateBuilder . Это позволяет создавать динамические запросы с семантикой «И» или «Или». Это бесплатно и стабильно - я использую его повсюду.

1 голос
/ 17 декабря 2009

Один из способов сделать это - манипулировать деревом выражений LINQ для вашего запроса. В вашем случае вам нужно будет создать лямбда-выражение и заменить его для вашего вызова на Where. Вот рабочий пример, основанный на списке, но код для управления деревом выражений одинаков независимо от поставщика запросов.

List<User> Users = new List<User>();
Users.Add(new User() { FirstName = "John", LastName = "Smith" });
Users.Add(new User() { FirstName = "Jane", LastName = "Smith" });


string Query = "John";

var Queryable = Users.AsQueryable();

var Results = (from u in Queryable
               select u);

//initial method call... the lambda u => false is a place-holder that is about to be replaced
MethodCallExpression WhereExpression = (MethodCallExpression)Results.Where(u => false).Expression;

//define search options
Expression<Func<User, string, bool>> FilterLastName = (u, query) => u.LastName.Contains(query);
Expression<Func<User, string, bool>> FilterFirstName = (u, query) => u.FirstName.Contains(query);

//build a lambda based on selected search options... tie the u parameter to UserParameter and the query parameter to our Query constant
ParameterExpression UserParameter = Expression.Parameter(typeof(User), "u");
Expression Predicate = Expression.Constant(false);  //for simplicity, since we're or-ing, we'll start off with false || ...

//if (condition for filtering by last name)
{
    Predicate = Expression.Or(Predicate, Expression.Invoke(FilterLastName, UserParameter, Expression.Constant(Query)));
}

//if (condition for filtering by first name)
{
    Predicate = Expression.Or(Predicate, Expression.Invoke(FilterFirstName, UserParameter, Expression.Constant(Query)));
}

//final method call... lambda u => false is the second parameter, and is replaced with a new lambda based on the predicate we just constructed
WhereExpression = Expression.Call(WhereExpression.Object, WhereExpression.Method, WhereExpression.Arguments[0], Expression.Lambda(Predicate, UserParameter));

//get a new IQueryable for our new expression
Results = Results.Provider.CreateQuery<User>(WhereExpression);

//enumerate results as usual
foreach (User u in Results)
{
    Console.WriteLine("{0} {1}", u.FirstName, u.LastName);
}

Работа с деревьями выражений обычно может быть упрощена с помощью шаблона посетителя, но я пропустил это, чтобы вы могли более четко видеть работу, которую необходимо выполнить.

0 голосов
/ 17 декабря 2009

Вот предложение.

Я не пробовал скомпилировать и запустить его, и LinqToSQL полон сюрпризов, поэтому никаких гарантий: -)

var ResultsFromProfiles = from AllPeeps in SearchDC.aspnet_Users select AllPeeps;

IEnumerable<AspNet_User> total = new AspNew_User[0];

if (SearchFirstNameBox.Checked)
{    
    total = total.Concat(ResultsFromProfiles.Where(p => p.tblUserProfile.FirstName.Contains(SearchTerm));}
}

if (SearchLastNameBox.Checked)
{
   total = total.Concat(ResultsFromProfiles.Where(p => p.tblUserProfile.LastName.Contains(SearchTerm));
}

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