【问题标题】:Write dynamic filter for Entity Framework Core为 Entity Framework Core 编写动态过滤器
【发布时间】: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;

}

对于特殊情况,我可以做些什么来实施?因为属性值在运行时是动态的。我无法检测到要使用的类型 &lt;=&gt;= ...

感谢您的支持

【问题讨论】:

  • 你将无法做到这一点。传递给Where 的表达式必须是可转换为 SQL 的有效表达式。因此,反射在这里不起作用。如果您需要使用反射,那么您也必须通过反射调用Where。坦率地说,我什至不明白这一点。看起来您正在尝试抽象出此处使用 LINQ 的事实,但您实际上是在创建自己的、效率较低且更复杂的 LINQ 版本来执行此操作。
  • @ChrisPratt 是的,我的要求是进行通用排序和过滤,并用于项目中的另一个模型。克里斯,我的要求有解决方案吗?感谢您的支持。
  • 我建议不要使用反射,而是在这里构建简单的表达式。我写了一个库来做到这一点:github.com/axelheer/nein-linq#dynamic-query-filtering--sorting

标签: c# linq entity-framework-core


【解决方案1】:

如您所见,您不能使用反射。

但是,有 2 个第三方库可以帮助您解决此问题

LINQ 动态

https://www.nuget.org/packages/System.Linq.Dynamic.Core/

所需的语法与 C# 略有不同,但效果很好。它是做这种事情的最受欢迎的图书馆。


C# 评估表达式

免责声明:我是项目的所有者C# Eval Expression

该库不是免费的,但您几乎可以使用与 C# 相同的语法来执行任何动态 LINQ。

因此,您将能够构建一个字符串进行评估,而库将为您完成剩下的工作。

以下是一些使用 EF Classic 的示例:

Dynamic linq 是否可以与 MySql、Sql Server 和 Postgresql、Jonathan 一起使用?

是的,我不明白为什么它不能工作。在引擎盖下,是生成您可以手动调用的 LINQ 表达式。

【讨论】:

  • @感谢您的支持,Dynamic linq 是否可以与 MySql、Sql Server 和 Postgresql 一起使用,Jonathan?
猜你喜欢
  • 2021-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-09
  • 2022-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多