【问题标题】:WhereIn with dynamic propertyWhereIn 具有动态属性
【发布时间】:2017-12-13 23:45:18
【问题描述】:

我想构建LINQ,稍后将其转换为sql 中的WHERE IN。在常规用例中,我会这样做:

querableIQuerable<T>arrIEnumerable<int>

querable = querable.Where(e => arr.Contains(e.Id));

但是

我的问题是我要过滤的值 (e.Id) 是动态的,我将它作为字符串获取。我该怎么做?

更多背景: 我正在做 REST API 端点,用户可以在其中发送他想要过滤值的列​​,所以示例是:

  1. filter: {"id": [1,2]}

我想翻译成queryable.Where(e => new [] {1,2}.Contains(e.Id))之类的东西

  1. filter: {"customerId": [4,5]}

我想翻译成queryable.Where(e => new [] {4,5}.Contains(e.CustomerId))之类的东西

所以基本上我的输入是一个列名,它是一个string 和一个 ID 列表,它是 IEnumerable<int>

感觉可以用Expression(类似this answer)实现,但是不知道怎么做。

【问题讨论】:

  • 我猜this 是您要查找的内容,但随后使用了参数化的属性名称。

标签: c# linq


【解决方案1】:

你可以这样做:

public static class QueryableExtensions {
    public static IQueryable<TEntity> WhereIn<TEntity, TValue>(this IQueryable<TEntity> query, string property, IEnumerable<TValue> values) {
        // x
        var arg = Expression.Parameter(typeof(TEntity), "x");
        // x.Property            
        var prop = Expression.Property(arg, property);
        // values.Contains(x.Property)
        var contains = Expression.Call(
            typeof(Enumerable),
            "Contains",
            new[] { typeof(TValue) },
            Expression.Constant(values),
            prop
        );
        // x => values.Contains(x.Property)
        var lambda = Expression.Lambda<Func<TEntity, bool>>(contains, arg);
        return query.Where(lambda);
    }
}

请注意,您传递的可枚举值的类型,并且属性类型应该匹配才能使其工作(因此,如果属性是 int 类型 - 传递整数数组)。

【讨论】:

  • 完美!非常感谢
猜你喜欢
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
  • 2017-01-22
  • 2021-09-13
  • 2011-12-09
  • 2011-11-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多