запрос linq to sql с несколькими параметрами where
в настоящее время я пишу функцию поиска в ASP.NET MVC 4 с Entity Framework. Однако я попал в тупик, для которого я могу найти только "плохие" решения.
моя функция поиска возвращает модель, которая состоит из 4 параметров:
String Name
String Street
String Code
String Province
List<Query> query = (from t in Model select t).ToList();
теперь я хотел бы отфильтровать ввод поиска. Однако пользователь может решить заполнить как можно больше полей поиска. Он может решить использовать имя и улицу, или имя, улицу и провинцию, или ...
в единственное реальное решение, которое я смог найти, состоит в том, чтобы сделать мой запрос и IQueryable
и проверьте, заполнено ли поле if
, а затем использовать .Where
обновить запрос.
Поскольку в настоящее время это даст M 5 запросов, мне интересно, есть ли лучшее решение, которое мне здесь не хватает.
Спасибо за помощь.
4 ответов
если я правильно вас понял. Вы можете захотеть что-то вроде этого:
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
когда вы добавляете операторы where и когда вы делаете ToList()
что sql будет выполняться.
обновление
чтобы ответить на комментарий Луиса Эрнандеса. Так вот как это работает. При выборе модели в этом случае тип коллекции IQueryable
. Это означает, что он не выполняется в отношении базы данных. Для запроса выполнить вам нужно применить некоторые из окончательных методов. Чтобы сказать linq, что он фактически выполнит вызов базы данных. Это, например,
ToList()
FirstOrDefault()
SingleOrDefault()
Single()
First()
ToDictionary()
поэтому, когда мы добавляем предложения Where без использования ToList()
. Выполнение запроса не выполняется.
пожалуйста, попробуйте запрос в помощью linqpad
используйте класс фильтра сущностей, который вы найдете здесь : 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
вы casn попробовать что-то вроде этого
from cars in tblCars
where (cars.colorID == 1) && (cars.Wieght > 500) && (cars.Active == true)
select cars;
решение Ариона, конечно, очень хорошо, Я попытался сделать его немного менее повторяющимся, используя отражение, надеюсь, это поможет.
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:
я отредактировал его для работы со всеми свойствами. конечно, вам все еще нужны некоторые вещи, чтобы это работало, но как только вы поймете, как с ним работать, вы можете использовать его в качестве утилиты для всего вашего кода, а не для его жесткого кодирования для каждого типа