You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用DynamicExpressionParser解析Lambda的Select方法报错,如何解决?

解决DynamicExpressionParser解析Select方法的问题

我正在使用DynamicExpressionParser,但需要解析Select方法,以下是我的代码:

using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Text.RegularExpressions;

var categories = new List<Dictionary<string, object>>
{
    new() {{"id", 1}, {"name", "Food"}},
    new() {{"id", 2}, {"name", "Drink"}},
    new() {{"id", 3}, {"name", "Snack"}}
};

var dict = new Dictionary<string, object> {{"categories", categories}};
// var codeToGetFirstCategoryName = "Category Name: ${categories[0][\"name\"]}"; // This is working
var codeToGetNames = "Category Names: ${string.Join(\"\", categories.Select(x => x[\"name\"]))}";
var result = StringHelper.Interpolate(codeToGetNames, dict);

Console.WriteLine(result);

public static class StringHelper
{
    public static string Interpolate(string text, Dictionary<string, object> row, string pattern = @"\$\{(?:<key>[^{}]*)}")
    {
        return Regex.Replace(text, pattern, match =>
        {
            var parameterExpressions = row.Select(column => Expression.Parameter(column.Value.GetType(), column.Key));
            var lambdaExpression = DynamicExpressionParser.ParseLambda(parameterExpressions.ToArray(), typeof(object), match.Groups["key"].Value, row.Values.ToArray());

            return lambdaExpression.Compile().DynamicInvoke(row.Values.ToArray())?.ToString() ?? string.Empty;
        });
    }
}

运行时抛出异常:

Unhandled exception. ')' or ',' expected (at index 38)


问题原因及修复方案

1. 正则表达式命名组错误

原正则中的<key>不是合法的命名组语法,无法正确提取${}内的表达式内容,需改为(?<key>[^{}]*)。

2. 动态表达式语法适配

DynamicExpressionParser的语法与原生C#有细微差异,同时需确保字符串转义正确。修正后的代码如下:

using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Text.RegularExpressions;

var categories = new List<Dictionary<string, object>>
{
    new() {{"id", 1}, {"name", "Food"}},
    new() {{"id", 2}, {"name", "Drink"}},
    new() {{"id", 3}, {"name", "Snack"}}
};

var dict = new Dictionary<string, object> {{"categories", categories}};
var codeToGetNames = "Category Names: ${string.Join(\", \", categories.Select(x => x[\"name\"]))}";
var result = StringHelper.Interpolate(codeToGetNames, dict);

Console.WriteLine(result);

public static class StringHelper
{
    public static string Interpolate(string text, Dictionary<string, object> row, string pattern = @"\$\{(?<key>[^{}]*)}")
    {
        return Regex.Replace(text, pattern, match =>
        {
            var parameterExpressions = row.Select(column => Expression.Parameter(column.Value.GetType(), column.Key)).ToArray();
            var expressionText = match.Groups["key"].Value;
            var lambdaExpression = DynamicExpressionParser.ParseLambda(parameterExpressions, typeof(object), expressionText);

            var compiled = lambdaExpression.Compile();
            return compiled.DynamicInvoke(row.Values.ToArray())?.ToString() ?? string.Empty;
        });
    }
}

替代方案:使用Roslyn脚本引擎

如果DynamicExpressionParser的语法限制无法满足需求,可以改用Roslyn脚本引擎,它支持完整的C#语法:

using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using System.Text.RegularExpressions;

var categories = new List<Dictionary<string, object>>
{
    new() {{"id", 1}, {"name", "Food"}},
    new() {{"id", 2}, {"name", "Drink"}},
    new() {{"id", 3}, {"name", "Snack"}}
};

var dict = new Dictionary<string, object> {{"categories", categories}};
var codeToGetNames = "Category Names: ${string.Join(\", \", categories.Select(x => x[\"name\"]))}";
var result = StringHelper.Interpolate(codeToGetNames, dict);

Console.WriteLine(result);

public static class StringHelper
{
    public static string Interpolate(string text, Dictionary<string, object> row, string pattern = @"\$\{(?<key>[^{}]*)}")
    {
        var options = ScriptOptions.Default.WithImports("System", "System.Linq", "System.Collections.Generic");
        return Regex.Replace(text, pattern, async match =>
        {
            var expressionText = match.Groups["key"].Value;
            var script = CSharpScript.Create<object>(expressionText, options, typeof(Dictionary<string, object>));
            var result = await script.RunAsync(row);
            return result.ReturnValue?.ToString() ?? string.Empty;
        }).Result;
    }
}

使用此方案需要安装NuGet包Microsoft.CodeAnalysis.CSharp.Scripting。

内容的提问来源于stack exchange,提问作者AliRıza Adıyahşi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 10:49:56