如何在动态选择中使用表达式创建“内联 if 语句”以进行 null 检查

2024-01-31

如何在动态选择中使用表达式创建“内联 if 语句”以进行 null 检查?

我为对象的嵌套属性编写了一个动态选择 LINQ 表达式,但当它为 null 时,它会引发异常。所以我想检查该属性是否为空,就这么简单!

这就是我的意思:

X.Where(...)
 .Select(X => new Y{
    ...
    Z = X.Titles == null ? "" : [Linq]
    ...
}).FirstOrDefault();

这是我写的

private static Expression GetLocalizedString(Expression stringExpression, SupportedCulture supportedCulture)
    {
        var expression = Expression.Parameter(typeof(APILocalizedString), nameof(APILocalizedString));
        
        var prop = Expression.Property(expression, nameof(APILocalizedString.SupportedCulture));
        var value = Expression.Constant(supportedCulture);
        var condition = Expression.Equal(prop, value);

        var where = Expression.Call(
            typeof (Enumerable),
            nameof(Enumerable.Where),
            new Type[] { typeof(APILocalizedString) },
            stringExpression,
            Expression.Lambda<Func<APILocalizedString, bool>>(condition, expression));

        var select = Expression.Call(
            typeof(Enumerable),
            nameof(Enumerable.Select),
            new Type[] { typeof(APILocalizedString), typeof(string) },
            where,
            Expression.Lambda<Func<APILocalizedString, string>>(
                Expression.Property(expression, nameof(APILocalizedString.Text)),
                expression
            ));

        var first = Expression.Call(
            typeof(Enumerable),
            nameof(Enumerable.First),
            new Type[] { typeof(APILocalizedString) },
            stringExpression);

        var defaultIfEmpty = Expression.Call(
            typeof(Enumerable),
            nameof(Enumerable.DefaultIfEmpty),
            new Type[] { typeof(string) },
            select,
            first);

        var firstOrDefault =
            Expression.Call(
            typeof(Enumerable),
            nameof(Enumerable.FirstOrDefault),
            new Type[] { typeof(string) },
            defaultIfEmpty);


        var nullCheck = Expression.Equal(stringExpression, Expression.Constant(null, stringExpression.Type));
        var result = Expression.IfThenElse(nullCheck, Expression.Constant(""), firstOrDefault);
            
        return result;
    }

这是 GetLocalizedString 生成的内容:

{IIF((X.Titles == null), "", X.Titles.Where(APILocalizedString => (APILocalizedString.SupportedCulture == EN)).DefaultIfEmpty(X.Titles.First()).Select(APILocalizedString => APILocalizedString.Text).FirstOrDefault())}

选择表达式

... bindings.Add(Expression.Bind(property, GetLocalizedString(Expression.Property(parameter, "Titles"), SupportedCulture.EN))); ...

这是错误消息:

System.ArgumentException: 'Argument types do not match'

Select 属性的类型为 String

有什么办法可以创建像这样的表达式X.Titles == null ? "" : [Linq] ?


相当于 C# 条件的表达式?:运算符是Expression.Condition https://learn.microsoft.com/en-us/dotnet/api/system.linq.expressions.expression.condition?view=netframework-4.7.2. While Expression.IfThenElse https://learn.microsoft.com/en-us/dotnet/api/system.linq.expressions.expression.ifthenelse?view=netframework-4.7.2你正在使用的相当于C#if then else block.

两种方法都返回ConditionalExpression https://learn.microsoft.com/en-us/dotnet/api/system.linq.expressions.conditionalexpression?view=netframework-4.7.2 with Test, IfTrue and IfFalse已填充属性。不同的是结果Type of the Condition是操作数的类型,而对于IfThenElse it is void,因此不能在查询表达式树中使用。

所以你的具体问题的答案是:

var result = Expression.Condition(nullCheck, Expression.Constant(""), firstOrDefault);

附:作为一个侧面节点,我从您的代码片段中收到了几个错误,因此我必须像这样重新排列它,以便使上面的行没有错误:

private static Expression GetLocalizedString(Expression stringExpression, SupportedCulture supportedCulture)
{
    var expression = Expression.Parameter(typeof(APILocalizedString), nameof(APILocalizedString));

    var prop = Expression.Property(expression, nameof(APILocalizedString.SupportedCulture));
    var value = Expression.Constant(supportedCulture);
    var condition = Expression.Equal(prop, value);

    var where = Expression.Call(
        typeof(Enumerable),
        nameof(Enumerable.Where),
        new Type[] { typeof(APILocalizedString) },
        stringExpression,
        Expression.Lambda<Func<APILocalizedString, bool>>(condition, expression));

    var first = Expression.Call(
        typeof(Enumerable),
        nameof(Enumerable.First),
        new Type[] { typeof(APILocalizedString) },
        stringExpression);

    var defaultIfEmpty = Expression.Call(
        typeof(Enumerable),
        nameof(Enumerable.DefaultIfEmpty),
        new Type[] { typeof(APILocalizedString) },
        where,
        first);

    var select = Expression.Call(
        typeof(Enumerable),
        nameof(Enumerable.Select),
        new Type[] { typeof(APILocalizedString), typeof(string) },
        defaultIfEmpty,
        Expression.Lambda<Func<APILocalizedString, string>>(
            Expression.Property(expression, nameof(APILocalizedString.Text)),
            expression
        ));

    var firstOrDefault =
        Expression.Call(
        typeof(Enumerable),
        nameof(Enumerable.FirstOrDefault),
        new Type[] { typeof(string) },
        select);


    var nullCheck = Expression.Equal(stringExpression, Expression.Constant(null, stringExpression.Type));
    var result = Expression.Condition(nullCheck, Expression.Constant(""), firstOrDefault);

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

如何在动态选择中使用表达式创建“内联 if 语句”以进行 null 检查 的相关文章

随机推荐

  • 可对动态内容进行排序

    所以我使用 jQuery UI 可排序插件对小图库中的照片进行排序 function area sortable items sort wrapper cursor move handle photo handler opacity 0 5
  • django:如何为 SuspiciousOperation 异常创建自定义日志过滤器?

    迁移到 1 11 从 1 8 后 我收到了一些SuspiciousOperation记录错误 它似乎来自 JS 请求 如果用户移动鼠标 它会保持会话活动 但这并不重要 我怎样才能过滤这个异常 我尝试过的 我刚刚在某处创建了一个过滤器 imp
  • 限制变量范围

    我正在尝试编写一个函数 它限制 R 变量的范围 例如 source LimitScope R y 0 f function Raises an error as y is a global variable x y 我想过测试可变环境 但不
  • 我应该如何更新“热门”表?

    我有一个带有 热 表的 postgres 数据库 这意味着它每秒都会收到许多更新 删除 我想运行一个查询UPDATE大约 10 的行 我没有 10 标准的索引 隔离级别设置为SERIALIZABLE作为数据库标志 影响所有事务 我希望这个查
  • Elixir Phoenix 生产服务器出现 Letscrypt 续订问题

    我有一个使用 Elixir Phoenix 框架构建的网站 该网站在开发和生产模式下都运行良好 当phoenix服务器在开发模式下运行时 我更新Let s Encrypt证书没有问题 但是当完全一样应用程序正在生产模式下运行 尝试更新时我不
  • 为什么Java的Area#equals方法不覆盖Object#equals?

    我刚刚遇到了一个由Java引起的问题java awt geom Area equals Area 方法 该问题可以简化为以下单元测试 org junit Test public void testEquals java awt geom A
  • Oracle 中数字的默认精度和小数位数是多少?

    在 Oracle 中创建 NUMBER 类型的列时 您可以选择不指定精度或小数位数 如果您不指定这些默认值 它们会做什么 数字 精度 小数位数 如果未指定精度 则该列将存储给定的值 如果未指定比例 则比例为零 更多信息请访问 http do
  • 检测iframe是否跨域的万无一失的方法

    我正在尝试确定是否有任何 iframe 是跨域的 根据这个问题中接受的答案 检测iframe何时跨域 然后退出它 https stackoverflow com questions 2365822 detect when iframe is
  • 在 C 中查找列表的基数

    我怎样才能只找到列表中出现一次的元素并返回基数 例如 如果我的列表由 3 2 1 1 2 4 组成 我期望返回计数器为 4 而不是6 因为我们不计算重复的数字 这是我到目前为止编写的代码 struct Node int data struc
  • 如何在 Android 中使用 LocationManager#getCurrentLocation

    我需要获取当前位置信息 目前 我正在使用获取最后的已知位置 https developer android com reference android location LocationManager getLastKnownLocatio
  • ASP.NET Core 中的通用存储库在 Startup.cs 中的每个表中没有单独的 AddScoped 行?

    我的项目中有一个通用存储库 考虑以下控制器片段 public class Lookup1Controller Controller readonly MyDbContext db public Lookup1Controller MyDbC
  • 如何在不阻塞 UI 线程的情况下继续执行多个任务?

    在我的 MVVM 应用程序中 我的视图模型调用 3 个不同的服务方法 将每个方法的数据转换为通用格式 然后使用属性通知 可观察集合等更新 UI 服务层的每个方法都会启动一个新的Task并返回Task到视图模型 这是我的一种服务方法的示例 p
  • 未选取 EF 的 Azure 网站连接字符串

    我正在将 ASP NET Web 应用程序部署到 Azure 网站 该网站使用实体框架 当我在中包含以下内容时Web config它运行良好
  • 如何使 Java 和 Objective-C (iPhone) 之间的 AES 加密相同?

    我正在使用 Objective C 加密一个字符串 并使用 AES 在 Java 中加密相同的字符串 并且看到一些奇怪的问题 结果的第一部分在一定程度上匹配 但随后就不同了 因此当我将结果从 Java 解码到 iPhone 上时 它无法解密
  • C++ 中的 std::async 和 lambda 函数没有给出关联状态

    我试图在方便的时候通过使用异步来获得更好的性能 我的程序可以编译 但每次使用包含异步调用的函数时都会出现以下错误 C exception with description No associated state 我尝试使用 lambda 调
  • C++ 中访问器方法(getter 和 setter)的约定

    关于 C 中的访问器方法的几个问题已经在 SO 上被问到了 但没有一个能够满足我对此问题的好奇心 我尽可能避免访问器 因为像 Stroustrup 和其他著名程序员一样 我认为一个类中有很多访问器是糟糕的 OO 的标志 在 C 中 在大多数
  • 使用 Promise 作为回调来反应 setState [重复]

    这个问题在这里已经有答案了 我在 React 中尝试使用 Promise 作为回调来 SetState 时收到错误 这可能是由于我的错误造成的 并且希望对 React 中的 set State 进行一些澄清 我收到的错误消息如下 错误 作为
  • 用户个人资料信息权限对话框中显示“未注册的 Android 应用程序”文本

    我已将 Google 登录集成到我的应用程序中 我每次都能成功登录 但是当我在设备中添加新的谷歌帐户并尝试使用该帐户登录时 我会看到附加的弹出对话框 我不明白为什么它说 未注册的 Android 应用程序 在这种情况下如何注册应用程序 附加
  • 将链接附加到当前 url 的末尾

    当我将 HTML 文件上传到我的网站时 a href 标签 链接将链接中的 URL 附加到当前 URL 的末尾 例如 如果我的网站是example com并且index html文件被放置在example com test链接是google
  • 如何在动态选择中使用表达式创建“内联 if 语句”以进行 null 检查

    如何在动态选择中使用表达式创建 内联 if 语句 以进行 null 检查 我为对象的嵌套属性编写了一个动态选择 LINQ 表达式 但当它为 null 时 它会引发异常 所以我想检查该属性是否为空 就这么简单 这就是我的意思 X Where