Linq to sql query с несколькими параметрами

В настоящее время я пишу функцию поиска в 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 запросов, мне интересно, есть ли лучшее решение, которое мне не хватает здесь.

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

Ответ 1

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

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

Ответ 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

Ответ 3

Вы можете попробовать что-то вроде этого

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

Ответ 4

Решение 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:

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