我想构建LINQ
,稍后会将其转换为WHERE IN
中的sql
。在常规用例中,我会这样做:
(querable
为IQuerable<T>
而arr
为IEnumerable<int>
)
querable = querable.Where(e => arr.Contains(e.Id));
BUT
我的问题是我想要过滤的值(e.Id
)是动态的,我把它作为一个字符串。我怎么能这样做?
更多背景: 我正在做REST API端点,用户可以通过哪个列发送他想要过滤的值,所以示例如下:
filter: {"id": [1,2]}
我希望将其翻译为queryable.Where(e => new [] {1,2}.Contains(e.Id))
filter: {"customerId": [4,5]}
我希望将其翻译为queryable.Where(e => new [] {4,5}.Contains(e.CustomerId))
所以基本上我的输入是一个列名string
和id列表IEnumerable<int>
我觉得可以使用Expression
(类似于this answer)来实现,但我不知道该怎么做。
答案 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 - 传递整数数组)。