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-запросов, я бы использовал string builder, чтобы добавить их к основному запросу strSQL. Но здесь, в Linq, я могу думать только об использовании условия IF, где я буду писать один и тот же запрос трижды, причем каждый блок IF имеет дополнительное условие. Есть ли лучший способ сделать это?



Спасибо за ваше время..

586   6  

6 ответов:

Если вы не называете 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();

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

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

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 и использовать условия if для присоединения выражений к предложению where.

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

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 полезны.

вот мой код, чтобы сделать подобную вещь. Это метод на моем 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 - это необязательно. Я использую для преобразования объектов строк базы данных в результирующие "фруктовые" объекты.

просто я использую его в моем предложении 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();
}

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

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();

Comments

    Ничего не найдено.