Подтвердить что ты не робот

Linq: добавление условий к условию where условно

У меня есть такой запрос

(from u in DataContext.Users
       where u.Division == strUserDiv 
       && u.Age > 18
       && u.Height > strHeightinFeet  
       select new DTO_UserMaster
       {
         Prop1 = u.Name,
       }).ToList();

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

Если бы это было сделано с использованием SQL-запросов, я бы использовал построитель строк, чтобы добавить их к основному запросу strSQL. Но здесь, в Linq, я могу думать только об использовании условия IF, где я буду писать один и тот же запрос трижды, с каждым блоком IF, имеющим дополнительное условие. Есть лучший способ сделать это?

4b9b3361

Ответ 1

Если вы не вызываете ToList() и ваше окончательное сопоставление с типом DTO, вы можете добавить предложения Where по мере продвижения и построить результаты в конце:

var query = from u in DataContext.Users
   where u.Division == strUserDiv 
   && u.Age > 18
   && u.Height > strHeightinFeet
   select u;

if (useAge)
   query = query.Where(u => u.Age > age);

if (useHeight)
   query = query.Where(u => u.Height > strHeightinFeet);

// Build the results at the end
var results = query.Select(u => new DTO_UserMaster
   {
     Prop1 = u.Name,
   }).ToList();

Это все равно приведет только к одному вызову базы данных, который будет эффективно так же эффективен, как и запись запроса за один проход.

Ответ 2

один вариант.

bool? age = null

(from u in DataContext.Users
           where u.Division == strUserDiv 
           && (age == null || (age != null && u.Age > age.Value))
           && u.Height > strHeightinFeet  
           select new DTO_UserMaster
           {
             Prop1 = u.Name,
           }).ToList();

или вы можете переключиться на синтаксис метода для linq и использовать, если условия для присоединения выражений к предложению where.

Ответ 3

Я обычно использую цепочку методов, но имею ту же проблему. И вот расширение, которое я использую

public static IQueryable<T> ConditionalWhere<T>(
        this IQueryable<T> source, 
        Func<bool> condition,
        Expression<Func<T, bool>> predicate)
    {
        if (condition())
        {
            return source.Where(predicate);
        }

        return source;
    }

Это помогает избежать разрывов цепи. Также полезны те же ConditionalOrderBy и ConditionalOrderByDescending.

Ответ 4

Вот мой код, чтобы сделать аналогичную вещь. Это метод для моего WCF SOAP Web Service api.

    public FruitListResponse GetFruits(string color, bool? ripe)
    {
        try
        {
            FruitContext db = new FruitContext();
            var query = db.Fruits.Select(f => f);
            if (color != null)
            {
                query = query.Where(f => f.Color == color);
            }
            if (ripe != null)
            {
                query = query.Where(f => f.Ripe == ripe);
            }
            return new FruitListResponse
            {
                Result = query.Select(f => new Fruit { Id = f.FruitId, Name = f.Name }).ToList()
            };
        }
        catch (Exception e)
        {
            return new FruitListResponse { ErrorMessage = e.Message };
        }
    }

Базовый запрос Select(f => f), что означает, в основном, ВСЕ, а предложения Where необязательно привязаны к нему. Конечный Select не является обязательным. Я использую для преобразования объектов строк базы данных в объекты результата "Плоды".

Ответ 5

Просто я использую его в разделе where where

    public IList<ent_para> getList(ent_para para){
     db.table1.Where(w=>(para.abc!=""?w.para==para.abc:true==true) && (para.xyz!=""?w.xyz==para.xyz:true==true)).ToList();
}

Ответ 6

На основе определенного условия добавьте условие ...

from u in DataContext.Users
where u.Division == strUserDiv 
&& u.Age != null ? u.Age > 18 : 1== 1
&& u.Height != null ? u.Height > 18 : 1== 1
&& u.Height != null ? u.Height > 18 : 1== 1
 select new DTO_UserMaster
       {
         Prop1 = u.Name,
       }).ToList();

Ответ 7

Предполагая следующий параметр,

Int? Age = 18;

Просто используя условные операторы && и ||, мы можем получить другую версию.

(from u in DataContext.Users
where u.Division == strUserDiv 
    && (Age == null || u.Age > Age)
    && (Param1 == null || u.param1 == Param1)
    && u.Height > strHeightinFeet
select new DTO_UserMaster
{
    Prop1 = u.Name,
}).ToList();

Как и Param1, вы можете добавить любое количество параметров для условия поиска.