子集合 List.Any 的表达式树

2023-11-23

我正在使用表达式树构建通用 linq 查询。在子集合上创建表达式时我陷入困境。由于类型不兼容,方法调用会崩溃。通常我知道该放什么,但是 Any() 方法调用让我感到困惑。我已经尝试了所有我能想到的类型,但没有成功。任何帮助,将不胜感激。

这是我的实体类:

public class Story : Entity
{
    public string Author { get; set; }

    public IList<string> Contributors { get; set; }
}

我想为其生成表达式树的查询:

var stories = new List<Story>();
stories.Where(p => p.Author.Contains("Test") || p.Contributors.Any(c => c.Contains("Test")));

到目前为止我得到了什么

public interface IFilterCriteria
{
    string PropertyToCompare { get; set; }
    object ValueToCompare { get; set; }
    FilterOperator FilterOperator { get; set; }
    bool IsList { get; set; }
    Expression Expression { get; set; }
}

public static IQueryable<T> Filter<T>(this IQueryable<T> query, IList<IFilterCriteria> filterCriterias, LogicalOperator logicalOperator = LogicalOperator.And)
{
    if (filterCriterias != null && filterCriterias.Any())
    {
        var resultCondition = filterCriterias.ToExpression(query, logicalOperator);

        var parameter = Expression.Parameter(query.ElementType, "p");

        if (resultCondition != null)
        {
            var lambda = Expression.Lambda(resultCondition, parameter);

            var mce = Expression.Call(
                typeof(Queryable), "Where",
                new[] { query.ElementType },
                query.Expression,
                lambda);

            return query.Provider.CreateQuery<T>(mce);
        }
    }
    return query;
}

public static Expression ToExpression<T>(this IList<IFilterCriteria> filterCriterias, IQueryable<T> query, LogicalOperator logicalOperator = LogicalOperator.And)
{
    Expression resultCondition = null;
    if (filterCriterias.Any())
    {
        var parameter = Expression.Parameter(query.ElementType, "p");

        foreach (var filterCriteria in filterCriterias)
        {
            var propertyExpression = filterCriteria.PropertyToCompare.Split('.').Aggregate<string, MemberExpression>(null, (current, property) => Expression.Property(current ?? (parameter as Expression), property));

            Expression valueExpression;
            var constantExpression = Expression.Constant(filterCriteria.ValueToCompare);

            if (!filterCriteria.IsList)
            {
                valueExpression = Expression.Convert(constantExpression, propertyExpression.Type);
            }
            else
            {
                valueExpression = Expression.Call(typeof (Enumerable), "Any", new[] {typeof (string)},
                                                  propertyExpression, filterCriteria.Expression,
                                                  Expression.Constant(filterCriteria.ValueToCompare,
                                                                      typeof (string)));
            }

            Expression condition;
            switch (filterCriteria.FilterOperator)
            {
                case FilterOperator.IsEqualTo:
                    condition = Expression.Equal(propertyExpression, valueExpression);
                    break;
                case FilterOperator.IsNotEqualTo:
                    condition = Expression.NotEqual(propertyExpression, valueExpression);
                    break;
                case FilterOperator.IsGreaterThan:
                    condition = Expression.GreaterThan(propertyExpression, valueExpression);
                    break;
                case FilterOperator.IsGreaterThanOrEqualTo:
                    condition = Expression.GreaterThanOrEqual(propertyExpression, valueExpression);
                    break;
                case FilterOperator.IsLessThan:
                    condition = Expression.LessThan(propertyExpression, valueExpression);
                    break;
                case FilterOperator.IsLessThanOrEqualTo:
                    condition = Expression.LessThanOrEqual(propertyExpression, valueExpression);
                    break;
                case FilterOperator.Contains:
                    condition = Expression.Call(propertyExpression, typeof(string).GetMethod("Contains", new[] { typeof(string) }), valueExpression);
                    break;
                case FilterOperator.StartsWith:
                    condition = Expression.Call(propertyExpression, typeof(string).GetMethod("StartsWith", new[] { typeof(string) }), valueExpression);
                    break;
                case FilterOperator.EndsWith:
                    condition = Expression.Call(propertyExpression, typeof(string).GetMethod("EndsWith", new[] { typeof(string) }), valueExpression);
                    break;
                default:
                    condition = valueExpression;
                    break;
            }

            if (resultCondition != null)
            {
                switch (logicalOperator)
                {
                    case LogicalOperator.And:
                        resultCondition = Expression.AndAlso(resultCondition, condition);
                        break;
                    case LogicalOperator.Or:
                        resultCondition = Expression.OrElse(resultCondition, condition);
                        break;
                }
            }
            else
            {
                resultCondition = condition;
            }
        }
    }
    return resultCondition;
}

这就是我使用表达式的方式:

var stories = new List<Story>();
var filters = new List<FilterCriteria>();
filter.Add(new FilterCriteria { ValueToCompare = "Test", PropertyToCompare = "Author", FilterOperator = FilterOperator.Contains });

Expression<Func<string, bool>> func  = t => t.Contains("Test");

filter.Add(new FilterCriteria { ValueToCompare = "Test", PropertyToCompare = "Contributors", FilterOperator = FilterOperator.Contains, Expression = func });

stories.Filter(filters, LogicalOperator.Or).ToList();

但是运行此代码后,我收到此错误,但无法解决

类型“System.Linq.Queryable”上没有通用方法“Any”兼容 与提供的类型参数和参数。无类型参数 如果该方法是非通用的,则应提供。描述:安 当前网页执行期间发生未处理的异常 要求。请查看堆栈跟踪以获取有关的更多信息 错误及其在代码中的起源。

异常详细信息:System.InvalidOperationException:没有通用方法 “System.Linq.Queryable”类型上的“Any”与提供的兼容 类型参数和参数。如果出现以下情况,则不应提供类型参数 该方法是非通用的。

来源错误:

第 184 行:{ 第 185 行:
var 重载 = typeof(Queryable).GetMethods().Single(mi => mi.Name == "任意" && mi.GetParameters().Count() == 2); 186行:
Expression.Call(typeof(Queryable), "Any", new[] { typeof(string) }, 属性表达式,或);第 187 行:
valueExpression = Expression.Call(typeof(Enumerable), "Any", new[] { typeof(string)}、propertyExpression 或 Expression.Constant("Test",


你不打电话Any代码中任意位置的方法。

你应该延长Contains, 例子:

case FilterOperator.Contains:
    // if collection
    if (propertyExpression.Type.IsGenericType &&
        typeof(IEnumerable<>)
            .MakeGenericType(propertyExpression.Type.GetGenericArguments())
            .IsAssignableFrom(propertyExpression.Type))
    {
        // find AsQueryable method
        var toQueryable = typeof(Queryable).GetMethods()
            .Where(m => m.Name == "AsQueryable")
            .Single(m => m.IsGenericMethod)
            .MakeGenericMethod(typeof(string));

        // find Any method
        var method = typeof(Queryable).GetMethods()
            .Where(m => m.Name == "Any")
            .Single(m => m.GetParameters().Length == 2)
            .MakeGenericMethod(typeof(string));

        // make expression
        condition = Expression.Call(
            null, 
            method,
            Expression.Call(null, toQueryable, propertyExpression), 
            filterCriteria.Expression
        );
    }
    else
    {
        condition = Expression.Call(propertyExpression, typeof(string).GetMethod("Contains", new[] { typeof(string) }), valueExpression);
    }
    break;

您还应该创建一个p范围 (Expression.Parameter(query.ElementType, "p"))否则你会得到variable 'p' of type 'WpfApplication2.Story' referenced from scope '', but it is not defined error.

你可能会通过parameter from Filter方法ToExpression method.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

子集合 List.Any 的表达式树 的相关文章

随机推荐

  • 如何终止与 SQL Server 2005 数据库的所有当前连接?

    我想重命名数据库 但不断收到数据库 无法获取独占锁 的错误 这意味着某些连接仍然处于活动状态 如何终止与数据库的所有连接以便重命名它 该方法的原因是亚当建议不起作用的是 在您循环活动连接的过程中 可以建立新的连接 并且您会错过这些连接 您可
  • 跨 C API 边界传递异常

    我正在用 C 编写一个库 它使用旧的 C API 我的库的客户端可以指定回调函数 这些函数是通过我的库间接调用的 而我的库是通过C API调用的 这意味着必须处理客户端回调中的所有异常 我的问题是 如何捕获边界一侧的异常 并在重新跨越 C
  • Azure Powershell - 检查资源是否存在

    我正在使用 Powershell 自动设置我的 Azure 环境 创建存储帐户 数据库 网站等 在开发过程中 我想要提供和拆除很多东西 很多时候 我想运行我的配置脚本并创建一个天蓝色资产如果它还不存在 但是 我还没有找到一种优雅的方法来做到
  • android studio gradle版本增量

    我正在尝试在 gradle android studio 中设置一个不错的小版本控制脚本 其中版本名称在每次构建时都会增加 而版本代码仅在我进行发布构建时才会增加 这可能吗 我认为可以解决这个问题的是检查下面的 if 语句是否是一个版本 但
  • Jersey 序列化/反序列化问题:抽象类型只能使用附加类型信息进行实例化

    我使用 jersey 进行序列化和反序列化 我已经使用 jersey 在 WebLogic 上创建了 REST 通道 我有包含抽象类的结果对象 Jersey 将此类的实现名称添加到结果元数据中 order type installation
  • 用代数方法简化平方根

    我想以代数方式简化整数的平方根 而不是以数字方式计算它 即 800应该20 2 not 28 2842712474619 我找不到任何方法通过编程来解决这个问题 对根下的数字进行因式分解 选出成对出现的因式 将其余的留在根下 800 2 x
  • 隐藏 TreeView 项目

    我一直在尝试隐藏 TreeView 中的项目 我使用自定义数据类型作为源 称为 SettingsMenuItem 它继承自 FrameworkElement 当前为 FrameworkContentElement 因为否则 TreeView
  • Java中的静态块[重复]

    这个问题在这里已经有答案了 前几天我正在查看一些代码 我发现 static 来自 C 我不知道为什么会出现这种情况 这不是一个错误 因为代码编译得很好 这个 静态 代码块是什么 It s a 静态初始化器 它在类加载 或准确地说是初始化 但
  • HTML5 中的 iframe 拉伸

    我有两个 html 文件 一个包含另一个带有 iframe 的文件 我想让这个 iframe 拉伸到父 html 的整个高度 所以第一个 html 文件 具有红色背景 如下所示 第二个 具有蓝色背景
  • Python:比较两个 csv 文件中的特定列

    假设我有两个 CSV 文件 file1 和 file2 其内容如下所示 file1 fred 43 Male 23 45 blue 1 bedrock avenue file2 fred 39 Male 23 45 blue 1 bedro
  • 如何在 Delphi XE3 中的 Firemonkey FM2 应用程序中设置非客户区的样式

    我之前在 Delphi XE2 时间范围内问过这个问题 当时的答案很漂亮丑陋的黑客 根据官方发行说明 现在 Delphi XE3 支持非客户端主题 在Firemonkey FM2中的Delphi XE3中如何做到这一点 我相信这一定与样式书
  • Jenkinsfile - 脚本管道语法中的条件阶段执行

    我们正在使用脚本管道我们的语法Jenkinsfile其中定义了很多阶段来构建和部署我们的代码 我们有一个用例 如果我正在做一个任务 我想运行我的所有阶段完整构建但如果我需要执行一些 AWS 路由 则仅运行一个特定阶段 我知道我可以使用if
  • 如果将 PendingIntent 上的标志设置为 0 会发生什么?

    当您将待处理意图的标志设置为 0 时 到底会发生什么 它只是不升起一个标志还是默认为其他标志之一 不 这是创建新 PendingIntent 的 默认 行为 无论该行为是否已存在 如果您想要更专门的行为 例如在底层 Intent 相同的情况
  • TinyTds 错误:Adaptive Server 连接超时

    我们正在 Rails 3 2 12 ruby 1 9 3 上使用当前的tinyTDS gem 0 6 2 运行 Ruby on Rails 应用程序 我们使用 MS SQL 2012 或 2014 并面临比平常更多的以下错误消息 TinyT
  • 如何将 16 位 PCM 音频字节数组转换为双精度或浮点数组?

    我正在尝试对 3gpp 音频文件执行快速傅里叶变换 该文件包含来自手机麦克风的 44100kHz 的 5 秒小录音 出于显而易见的原因 我能找到的每个 Java FFT 算法都只接受 double float 或 Complex 输入 但我
  • 将 Azure 磁盘附加到 AKS pod 时出现权限错误

    我已经与这个错误作斗争了几个小时了 找到了几篇文章 但到目前为止没有任何帮助 我的工作基于 操作指南 gt 配置数据卷 gt Azure 磁盘 静态 https learn microsoft com en us azure aks azu
  • C++ 中的变量到底是什么?

    标准说 A variable通过对象的声明引入 变量的名称表示对象 但这个定义实际上意味着什么 变量是否为对象提供名称 即变量是否只是匿名对象的命名机制 或者变量就是名称本身 或者变量是否是一个命名对象 因为每个变量也是一个对象 或者变量只
  • 为什么 check_box 表单助手会生成两个复选框,其中一个是隐藏的?

    这段代码 form fo store products 做 f f check box track inventory 创建这个 html
  • 如何通过 jQuery 设置光标图像?

    在网络应用程序中 我有一个加载事件 如果浏览器正在从服务器加载数据 我希望光标更改为显示时钟的 gif 如何更改光标外观 我只在参考光标外观的博客中找到了这个 this css cursor move 我想改为加载图像 试试这个方法 thi
  • 子集合 List.Any 的表达式树

    我正在使用表达式树构建通用 linq 查询 在子集合上创建表达式时我陷入困境 由于类型不兼容 方法调用会崩溃 通常我知道该放什么 但是 Any 方法调用让我感到困惑 我已经尝试了所有我能想到的类型 但没有成功 任何帮助 将不胜感激 这是我的