从 Queryable 中获取 Where 方法

Posted

技术标签:

【中文标题】从 Queryable 中获取 Where 方法【英文标题】:Get Where method from Queryable 【发布时间】:2021-12-23 05:39:28 【问题描述】:

以下查询从 Queryable 返回两个 Where 方法:

    var foundedMethods = typeof(Queryable).GetMethods()
        .Where(m => m.Name == nameof(Queryable.Where) && 
                    m.GetParameters().Length == 2)
        .Where(p => p.GetParameters().First().ParameterType.GetGenericTypeDefinition() == typeof(IQueryable<>)
                    && p.GetParameters().Last().ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)).ToList();

我收到了两个针对QueryableWhere 方法调用。但是,我只需要以下内容:

Where<TSource>(IQueryable<TSource>, Expression<Func<TSource,Boolean>>)

我需要在上面的查询中添加什么添加过滤器?任何指南和帮助我如何按特定参数过滤方法?

【问题讨论】:

【参考方案1】:

按照问题的风格,检查 func 是否还具有正确数量的泛型 args 就足够了,因为返回的另一个重载有一个额外的 (Func&lt;TSource,Int32,Boolean&gt;)

最好在 Func 上进行与表达式参数相同的类型检查,但目前没有必要。

var foundedMethods = typeof(Queryable).GetMethods()
    .Where(m => m.Name == nameof(Queryable.Where)
                && m.GetParameters().Length == 2)
    .Where(p => p.GetParameters().First().ParameterType.GetGenericTypeDefinition() == typeof(IQueryable<>)
                && p.GetParameters().Last().ParameterType.GetGenericTypeDefinition() == typeof(Expression<>)
                // Ensure Func has 2 args
                && p.GetParameters().Last().ParameterType.GetGenericArguments().First().GetGenericArguments().Length == 2)
    .ToList();

或者,一种hack-y方法是通过匹配MethodInfo.ToString()直接找到方法签名

var foundedMethods = typeof(Queryable).GetMethods()
    .Where(m => m.ToString() ==
        "System.Linq.IQueryable`1[TSource] Where[TSource](System.Linq.IQueryable`1[TSource], System.Linq.Expressions.Expression`1[System.Func`2[TSource,System.Boolean]])")
    .ToList();

【讨论】:

以上是关于从 Queryable 中获取 Where 方法的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate Queryable不允许字符串比较

协议 Ecto.Queryable 未实现

EF Core 中DbContext不会跟踪聚合方法和Join方法返回的结果

哪些 ORM 工具支持这个版本的 Queryable.Select 扩展方法

实体一对多高效查询

MethodInfo 用于 EntityCollection 而不是 Queryable