如何根据一个实体输入参数过滤IEnumerable的 [英] How to filter IEnumerable based on an entity input parameter
问题描述
我现在使用实体框架 - 但它的所有ORM的,甚至IEnumerable的。
之间共享一个问题让我们说我有在MVC的方法是这样的:
[HttpPost]
公众的ActionResult美孚(FooModel模型)
{
VAR语境=新的上下文(); - 在EF会议
VAR数据= context.Foo.Where(???)了ToList()。
返回查看(数据);
}
欲基于输入参数来查询上下文像
VAR数据= context.Foo.Where(X => x.Date == model.Date&放大器;&安培;
x.Name == model.Name&放大器;&安培;
x.Item code = model.Item code).ToList();
但它比这更复杂,因为如果以上(日期
\\ 名称的参数之一
\\ 项目code
)为空,我不想把它列入查询里面。结果
如果我硬code它可以类似于这样:
VAR的查询= context.Foo;如果(model.Date!= NULL)
查询= query.Where(X => x.Date == model.Date);如果(model.Item code!= NULL)
查询= query.Where(X => x.Item code == model.Item code);
...
有必须比这个更简单的方法。结果,
我需要一种方法来生成类型的前pression 防爆pression< T,BOOL>
将在Where方法使用
[HttpPost]
公众的ActionResult美孚(FooModel模型)
{
VAR语境=新的上下文(); - 在EF会议
VAR数据= context.Foo.Where(THE_EX preSSION).ToList();
返回查看(数据);
}
有没有构建前pression一个内置的方式吗?是否有一个的NuGet包,不是吗?
更新:有可能是在模型实体超过30型属性;写30倍,其中对于每个查询都可以在颈部疼痛:
。凡(model.Date =空,X =>!x.Date == model.Date)
。凡(!model.Name =空,X => x.Name == model.Name)
。凡(!model.Item code =空,X => x.Item code == model.Item code)
...
...
...
.ToList();
尝试。这是使用反射和前pressions动态地建立查询。我只使用对象进行了测试。
静态的IQueryable< T>过滤< T>(IQueryable的< T>山坳,T过滤器)
{
的foreach(typeof运算中的VAR PI(T).GetProperties())
{
如果(pi.GetValue(过滤器)!= NULL)
{
VAR参数=前pression.Parameter(typeof运算(T),T);
VAR体=前pression.Equal(
防爆pression.PropertyOrField(参数,pi.Name)
防爆pression.PropertyOrField(前pression.Constant(过滤器),pi.Name));
VAR波长=前pression.Lambda<&Func键LT; T,BOOL>>(机身,参数);
COL = col.Where(拉姆达);
}
} 返回关口;
}
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();
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;
}
这篇关于如何根据一个实体输入参数过滤IEnumerable的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!