如何根据实体输入参数过滤IEnumerable
我正在使用现在的entity framework – 但它是所有ORM甚至IEnumerable之间“共享”的问题。
假设我在MVC中有一个方法如下所示:
[HttpPost] public ActionResult Foo(FooModel model) { var context = new Context(); -- The EF session var data = context.Foo.Where(???).ToList(); return View(data); }
我想根据输入参数查询上下文,如:
var data = context.Foo.Where(x => x.Date == model.Date && x.Name == model.Name && x.ItemCode = model.ItemCode).ToList();
但它比这更复杂,因为如果上面的一个参数( Date
Name
ItemCode
)为null,我不想将它包含在查询中。
如果我硬编码它看起来像这样:
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); ...
必须有一个比这更简单的方法。
我需要一种方法来生成要在Where方法中使用的Expression
类型的Expression
。
[HttpPost] public ActionResult Foo(FooModel model) { var context = new Context(); -- The EF session var data = context.Foo.Where(THE_EXPRESSION).ToList(); return View(data); }
是否有内置的方法来构建该表达式? 在nuget中有一个包吗?
更新:模型实体中可能有超过30个属性; 写30次每个查询的位置可能是一个痛苦的脖子:
.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();
试试吧。 这是使用reflection和表达式动态构建查询。 我只用物体测试过它。
static IQueryable Filter (IQueryable 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>(body, param); col = col.Where(lambda); } } return col; }
您的硬编码方法通常是最好的方法。
但是,您可以尝试通过编写适当的扩展方法来帮助保持代码清洁,从而使您的生活更轻松。
试试这个例子:
public static class QueryableEx { public static IQueryable Where ( this IQueryable @this, bool condition, Expression> @where) { return condition ? @this.Where(@where) : @this; } }
现在你可以编写这段代码:
[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); } }
(请不要忘记处理您的上下文或使用它来为您完成。)
我认为你应该将你的逻辑封装到你的Foo实体中,例如
public Foo { public bool isMatch(Model model) { // check your rules and return result } }
并在linq中使用它。 或者看看规格模式
上述就是C#学习教程:如何根据实体输入参数过滤IEnumerable分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1019608.html