Csharp/C#教程:如何根据实体输入参数过滤IEnumerable分享


如何根据实体输入参数过滤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

(0)
上一篇 2022年1月4日
下一篇 2022年1月4日

精彩推荐