2009-12-17 2 views
1

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

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; 

Это принеси мне все профили, где первое имя или фамилия содержит условие поиска.

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

Любые советы?

ответ

4

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

+0

OMG Я не знал об этом предикатаBuilder – Matias

+0

Ох, это выглядит красиво. Особенно по сравнению с альтернативным предложением (см. Мою запись ниже) –

+0

Блестящий, это именно то, что мне было нужно и очень просто/элегантно. Спасибо – Adam

0

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

Я никогда не пытался скомпилировать и запустить его, и 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(); 
1

Один из способов сделать это, чтобы манипулировать дерева выражений 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); 
} 

Working with expression trees обычно можно упростить, используя шаблон посетителя, но я пропустил, что так вы более четко могли видеть работу, которую предстоит сделать.

Смежные вопросы