2012-04-18 3 views
11

В настоящее время я пишу функцию поиска в ASP.NET MVC 4 с помощью Entity Framework. Тем не менее, я попал в блокпост, для которого я могу найти только «плохие» решения.linq to sql query с несколькими параметрами

Мои функции поиска получает обратно модель, которая состоит из 4-х параметров:

String Name 
String Street 
String Code 
String Province 

List<Query> query = (from t in Model select t).ToList(); 

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

Единственное реальное решение, которое я смог найти, состоит в том, чтобы сделать мой запрос и IQueryable и проверить, было ли поле заполнено с if, затем используйте .Where для обновления запроса. Поскольку это в настоящее время дает m 5 запросов, мне интересно, есть ли лучшее решение, которое мне не хватает здесь.

Спасибо, что помогли мне.

ответ

22

Если я понимаю вас правильно. Вы могли бы хотеть что-то вроде этого:

string Name; 
string Street; 
string Code; 
string Province; 
var query=(from t in Model select t); 
if(Name!=null) 
{ 
    query=query.Where (q =>q.Name==Name); 
} 
if(Street!=null) 
{ 
    query=query.Where (q =>q.Street==Street); 
} 
if(Code!=null) 
{ 
    query=query.Where (q =>q.Code==Code); 
} 
if(Province!=null) 
{ 
    query=query.Where (q =>q.Province==Province); 
} 
List<Query> ls = query.ToList(); 

Вы будете иметь IQueryable, когда вы добавляете где заявления и когда вы делаете ToList(), что SQL будет выполняться.

Update

Чтобы ответить на комментарий Луиса Эрнандеса. Так вот как это работает. Когда вы выбираете модель, в этом случае тип коллекции - IQueryable. Это означает, что он не был выполнен против базы данных. Для выполнения запроса вам необходимо применить некоторые из окончательного метода. Чтобы сообщить linq, что он действительно выполнит вызов базы данных. Это, например

ToList() 
FirstOrDefault() 
SingleOrDefault() 
Single() 
First() 
ToDictionary() 

Так что, когда мы добавляем в ИНЕКЕ без использования ToList(). Выполнение запроса не выполняется.

Пожалуйста, попробуйте запрос в LinqPad

+0

Да, это решение, которое я нашел в Интернете. Мне было интересно, есть ли более чистый способ кодировать это. – whodares

+0

Если вы хотите остановиться 'IQueryable'. Тогда это то, что я думаю, способ сделать это – Arion

+0

Может быть, есть больше кода, но это самый оптимизированный (и, вероятно, лучший). Проверьте полученный SQL-запрос в [linqpad] (http://www.linqpad.net/) – mshsayem

0

Вы casn попробовать некоторые вещи, как этот

from cars in tblCars 
where (cars.colorID == 1) && (cars.Wieght > 500) && (cars.Active == true) 
select cars; 
2

Используйте класс фильтра Entity вы найдете здесь: https://servicelayerhelpers.codeplex.com/SourceControl/changeset/view/32810#537055

поэтому сначала указать свой фильтр и после этого просто примените его к вашему запросу.

Пример:

var filter = EntityFilter 
.Where(c => c.Name == came) 
.Where(c => c.City == city); 

var customers = FindCustomers(filter); 

Customer[] FindCustomers(IEntityFilter filter) 
{ 
var query = context.Customers; 
query = filter.Filter(query); 
return query.ToArray(); 
} 

подробнее о: https://cuttingedge.it/blogs/steven/pivot/entry.php?id=66

0

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

 Type myType = myObject.GetType(); 
     IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties()); 

     foreach (PropertyInfo prop in props) 
     { 
      object propValue = prop.GetValue(myObject, null); 
      if (propValue != null) 
      { 
       query = query.Where(q => prop.GetValue(q, null) == propValue); 
      } 
     } 

EDIT:

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

+0

Спасибо за ответ, но это работает только для указанного вами значения Name. Поскольку у меня есть еще 3 значения, я не вижу, как это может сработать. – whodares