I\'m using now Entity framework- but it\'s a problem \"shared\" between all ORM\'s and even IEnumerable.
Let\'s say I have a method in MVC looks like this:
Try that. This is using reflection and expressions to build the query dynamically. I tested it only with objects.
static IQueryable<T> Filter<T>(IQueryable<T> col, T filter)
{
foreach (var pi in typeof(T).GetProperties())
{
if (pi.GetValue(filter) != null)
{
var param = Expression.Parameter(typeof(T), "t");
var body = Expression.Equal(
Expression.PropertyOrField(param, pi.Name),
Expression.PropertyOrField(Expression.Constant(filter), pi.Name));
var lambda = Expression.Lambda<Func<T, bool>>(body, param);
col = col.Where(lambda);
}
}
return col;
}
Your hard coded method is the best method generally.
However you can try to make your life a little easier by writing an appropriate extension method to help keep the code clean.
Try this for example:
public static class QueryableEx
{
public static IQueryable<T> Where<T>(
this IQueryable<T> @this,
bool condition,
Expression<Func<T, bool>> @where)
{
return condition ? @this.Where(@where) : @this;
}
}
Now you could write this code:
[HttpPost]
public ActionResult Foo(FooModel model)
{
using (var context = new Context())
{
var data = context.Foo
.Where(model.Date != null, x => x.Date == model.Date)
.Where(model.Name != null, x => x.Name == model.Name)
.Where(model.ItemCode != null, x => x.ItemCode == model.ItemCode)
.ToList();
return View(data);
}
}
(Please don't forget to dispose of your context or use using
to do it for you.)
I think you should encapsulate your logic into your Foo entity, e.g.
public Foo
{
public bool isMatch(Model model)
{
// check your rules and return result
}
}
and use it in linq. Or look at Specification pattern