WhereIn具有动态属性

时间:2017-12-13 15:21:43

标签: c# linq

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

querableIQuerable<T>arrIEnumerable<int>

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

BUT

我的问题是我想要过滤的值(e.Id)是动态的,我把它作为一个字符串。我怎么能这样做?

更多背景: 我正在做REST API端点,用户可以通过哪个列发送他想要过滤的值,所以示例如下:

  1. filter: {"id": [1,2]}
  2. 我希望将其翻译为queryable.Where(e => new [] {1,2}.Contains(e.Id))

    1. filter: {"customerId": [4,5]}
    2. 我希望将其翻译为queryable.Where(e => new [] {4,5}.Contains(e.CustomerId))

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

      我觉得可以使用Expression(类似于this answer)来实现,但我不知道该怎么做。

1 个答案:

答案 0 :(得分:2)

你可以这样做:

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 - 传递整数数组)。