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:
[HttpPost]
public ActionResult Foo(FooModel model)
{
var context = new Context(); -- The EF session
var data = context.Foo.Where(???).ToList();
return View(data);
}
I want to query the context based on the input parameter like:
var data = context.Foo.Where(x => x.Date == model.Date &&
x.Name == model.Name &&
x.ItemCode = model.ItemCode).ToList();
But it's more complicated than that, because if one of the parameters above(Date
\ Name
\ ItemCode
) is null I don't want to include it inside the query.
If I hard code it can looks similar to this:
var query = context.Foo;
if (model.Date != null)
query =query.Where(x => x.Date == model.Date);
if (model.ItemCode != null)
query =query.Where(x => x.ItemCode == model.ItemCode);
...
There must be a simpler way than this.
I need a way to generate an expression of the type Expression<T, bool>
to be used in the Where method.
[HttpPost]
public ActionResult Foo(FooModel model)
{
var context = new Context(); -- The EF session
var data = context.Foo.Where(THE_EXPRESSION).ToList();
return View(data);
}
Is there a built-in way to build that expression? Is there a package in nuget that does it?
Update: There could be more than 30 properites in the model-entity; writing 30 times the Where for each query can be a pain in the neck:
.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();
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:
Now you could write this code:
(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.
and use it in linq. Or look at Specification pattern
Try that. This is using reflection and expressions to build the query dynamically. I tested it only with objects.