【发布时间】:2019-03-28 17:04:06
【问题描述】:
我正在编写一个使用 .net Core 和 Entity Framework 的小项目。
我需要为IQueryable<T> 实现动态过滤器。
我有定义运算符的枚举
public enum QueryOperatorEnums
{
Equal = 0,
NotEqual = 1,
Constant = 2,
LessThan = 3,
GreaterThan = 4,
LessThanOrEqual = 5,
GreaterThanOrEqual = 6,
}
我有一个IQueryable 的扩展名:
public static IQueryable<T> Filter<T>(this IQueryable<T> query, Dictionary<string, KeyValuePair<QueryOperatorEnums, object>> keyValuePairs)
{
if (keyValuePairs == null)
return query;
foreach (var keyValuePair in keyValuePairs)
{
var propertyInfo = typeof(T).GetProperty(keyValuePair.Key);
if (propertyInfo != null)
{
var operation = keyValuePair.Value;
switch (operation.Key)
{
case QueryOperatorEnums.Constant:
break;
case QueryOperatorEnums.Equal:
query = query.Where(obj => propertyInfo.GetValue(obj, null).Equals(operation.Value));
break;
case QueryOperatorEnums.GreaterThan:
break;
case QueryOperatorEnums.GreaterThanOrEqual:
break;
case QueryOperatorEnums.LessThan:
break;
case QueryOperatorEnums.LessThanOrEqual:
break;
case QueryOperatorEnums.NotEqual:
break;
default:
break;
}
}
}
return query;
}
对于特殊情况,我可以做些什么来实施?因为属性值在运行时是动态的。我无法检测到要使用的类型 <=、>= ...
感谢您的支持
【问题讨论】:
-
你将无法做到这一点。传递给
Where的表达式必须是可转换为 SQL 的有效表达式。因此,反射在这里不起作用。如果您需要使用反射,那么您也必须通过反射调用Where。坦率地说,我什至不明白这一点。看起来您正在尝试抽象出此处使用 LINQ 的事实,但您实际上是在创建自己的、效率较低且更复杂的 LINQ 版本来执行此操作。 -
@ChrisPratt 是的,我的要求是进行通用排序和过滤,并用于项目中的另一个模型。克里斯,我的要求有解决方案吗?感谢您的支持。
-
我建议不要使用反射,而是在这里构建简单的表达式。我写了一个库来做到这一点:github.com/axelheer/nein-linq#dynamic-query-filtering--sorting
标签: c# linq entity-framework-core