c# - 如何根据实体输入参数过滤 IEnumerable

标签 c# .net asp.net-mvc entity-framework nhibernate

我现在正在使用 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);
...

一定有比这更简单的方法。
我需要一种方法来生成 Expression<T, bool> 类型的表达式在 Where 方法中使用。

[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 可能会让人头疼:

.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();

最佳答案

试试吧。这是使用反射和表达式来动态构建查询。我仅使用对象对其进行了测试。

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;
}

关于c# - 如何根据实体输入参数过滤 IEnumerable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12404136/

相关文章:

c# - 在 ToDictionary 之前执行 ToList() 是否更好?

c# - 如何获取属性树的踪迹?

jquery - 对象不支持属性或方法 'valid'

c# - 从 MVC Controller 验证 SignalR

asp.net-mvc - ASP.Net MVC 5 身份角色添加到数据库但 User.IsInRole 总是返回 false

c# - XAML ListView ItemContainer 高度

c# - AspNetCore 集成测试多个 WebApplicationFactory 实例?

c# - 如何使用 C# 舍入到最接近的 .5

.NET 包装调用/回调对以显示同步

c# - Entity Framework 数据传输对象最佳实践