Dynamic Where condition with Queryover
Asked Answered
B

1

1

I have an application and I'm trying to implement DDD concepts. I have my repository class with some method to list entities. I would like to know how can I do a query with QueryOver to filter separating with AND operator, when the parameter is filled, sample

public IEnumerable<Product> FindProducts(string name, decimal? price, DateTime? validDate, int? stock, int? idSupplier)
{
   var query = Session.QueryOver<Product>().OrderBy(x => x.Name).Asc;

   if (!string.IsNullOrEmpty(name))
      // add where condition for name parameter

   if (price.HasValue)
      // add 'AND' where condition for price parameter

   if (validDate.HasValue)
      // add 'AND' where condition for validDate parameter

   if (idSupplier.HasValue)
      // add 'AND' where condition for idSupplier parameter

   // other possible conditions

   return query.List();
}

Is there any way to do that before I use HQL string query? hehehe

Thank you!

Barri answered 5/6, 2012 at 12:8 Comment(0)
O
3

Here, use PredicateBuilder:

How To:

IQueryable<Product> SearchProducts (params string[] keywords)
{
  var predicate = PredicateBuilder.False<Product>();

  foreach (string keyword in keywords)
  {
    string temp = keyword;
    predicate = predicate.Or (p => p.Description.Contains (temp));
  }
  return dataContext.Products.Where (predicate);
}

PredicateBuilder Source:

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;

public static class PredicateBuilder
{
  public static Expression<Func<T, bool>> True<T> ()  { return f => true;  }
  public static Expression<Func<T, bool>> False<T> () { return f => false; }

  public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
                                                      Expression<Func<T, bool>> expr2)
  {
    var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
    return Expression.Lambda<Func<T, bool>>
          (Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
  }

  public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
                                                       Expression<Func<T, bool>> expr2)
  {
    var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
    return Expression.Lambda<Func<T, bool>>
          (Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
  }
}

For more information on PredicateBuilder and LinqKit go here: http://www.albahari.com/nutshell/linqkit.aspx

Orvah answered 5/6, 2012 at 12:28 Comment(7)
Yes I know i can do the second way, bu how can I add other possible conditions in it?Barri
@felipeoriani read up on predicate builder, assuming you're OK with a 3rd party lib (a lot of people use it, it's safe ;-), then I'd use that.Orvah
Great code, I will try it , thanks :)... I didn't know this lib, where can I find it? Thanks []sBarri
Just use the code I put here, use it in your own solution. The lib itself is just this code. You can reference it, or include it in your own project so you can manipulate it easier! Also, don't forget to upvote/mark as answer ;) More information on PredicateBuilder is available here: albahari.com/nutshell/predicatebuilder.aspxOrvah
More information on PredicateBuilder - albahari.com/nutshell/predicatebuilder.aspx More usage examples and whatnotOrvah
Thanks man, only one more question, can I integrate it with QueryOver of Nhibernate, I mean, how can I do a condition using 'like' operation? thanks for the link!Barri
Type out some code in the way you would EXPECT it to work and I'll be happy to take a look. But right now I'm not sure I understand your question! ;)Orvah

© 2022 - 2024 — McMap. All rights reserved.