Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework Linq表达式树-串联值数组_Entity Framework_Linq_Linq To Sql_Lambda_Linq To Entities - Fatal编程技术网

Entity framework Linq表达式树-串联值数组

Entity framework Linq表达式树-串联值数组,entity-framework,linq,linq-to-sql,lambda,linq-to-entities,Entity Framework,Linq,Linq To Sql,Lambda,Linq To Entities,我目前正在使用一个.net核心(vnext)解决方案,该解决方案使用linq和实体框架核心 我们使用Microsoft.Linq.Translations将计算列定义存储为lambda表达式,以便在需要时将它们注入到语句中。计算定义的示例如下所示: private static readonly CompiledExpression<Model, string> fullNameExpression = aTranslation<Model>.Expres

我目前正在使用一个.net核心(vnext)解决方案,该解决方案使用linq和实体框架核心

我们使用Microsoft.Linq.Translations将计算列定义存储为lambda表达式,以便在需要时将它们注入到语句中。计算定义的示例如下所示:

private static readonly CompiledExpression<Model, string> fullNameExpression =
        aTranslation<Model>.Expression(e => e.FullName, e => $"{e.FirstName} {e.LastName} ({e.Code})");
因此,如果我将计算定义更改为以下内容(注意,我只是手动构建字符串,而不是使用string.format:

private static readonly CompiledExpression<Model, string> fullNameExpression =
        aTranslation<Model>.Expression(e => e.FullName, e => e.FirstName + " " + e.LastName + "(" + e.Code + ")");
因此,除了更改编写/定义计算定义的方式外,我正在尝试编写一个层,该层接受使用字符串格式linq表达式编写的定义,并将该表达式替换为第二种类型(如字符串连接)

我通过截取字符串格式表达式并构建成员和常量表达式的列表/数组(即。 名字, " ", 姓, " (" 等等

我尝试使用字符串concat方法,通过循环遍历值并计算左表达式和右表达式,但这最终导致了其他一些不起作用的结果:

.Call System.String.Concat(
.Call System.String.Concat(
    .Call System.String.Concat(
        .Call System.String.Concat(
            $e.FirstName,
            " "),
        $e.LastName),
    " ("),
$e.Code)
现在,我被困在如何转换表达式列表以生成这种表达式的问题上:

 .Lambda #Lambda1<System.Func`2[Model,System.Boolean]>(Model $e) {
.Call ($e.FirstName + " " + $e.LastName + " (" + $e.Code + ")").Contains("Bob")}

好吧,我想出来了

@usr的评论促使我进一步深入研究语法树,看看代码是如何编译的。我在“视图->其他窗口->语法可视化工具”下使用了VS2015中内置的语法可视化工具

当分解期望结果的标准linq表达式时,这表明在幕后这是编译成一个看起来很奇怪的二进制运算符

最初,我尝试将string.concat调用替换为:

BinaryExpression.Add(concatArgs[0], concatArgs[1])
但是,这导致了以下错误:

未为类型“System.String”定义二进制运算符Add 和“System.String”

这让我想到了这篇文章/帖子:

对于建议的过载:

基本上,在幕后,所有这些最终都会转换为string.concat调用,但是使用BinaryExpression.Add方法似乎允许linq在运行时解决这个问题,并且只使用一个对string.concat的调用?可能是“params object[]”

无论如何,将我的GenerateStringConcat方法更改为以下方法已经达到了目的:

private Expression GenerateStringConcat(Expression left, Expression right)
{
    return BinaryExpression.Add(left, right, typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }));
}

好吧,我想出来了

@usr的评论促使我进一步深入研究语法树,看看代码是如何编译的。我在“视图->其他窗口->语法可视化工具”下使用了VS2015中内置的语法可视化工具

当分解期望结果的标准linq表达式时,这表明在幕后这是编译成一个看起来很奇怪的二进制运算符

最初,我尝试将string.concat调用替换为:

BinaryExpression.Add(concatArgs[0], concatArgs[1])
但是,这导致了以下错误:

未为类型“System.String”定义二进制运算符Add 和“System.String”

这让我想到了这篇文章/帖子:

对于建议的过载:

基本上,在幕后,所有这些最终都会转换为string.concat调用,但是使用BinaryExpression.Add方法似乎允许linq在运行时解决这个问题,并且只使用一个对string.concat的调用?可能是“params object[]”

无论如何,将我的GenerateStringConcat方法更改为以下方法已经达到了目的:

private Expression GenerateStringConcat(Expression left, Expression right)
{
    return BinaryExpression.Add(left, right, typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }));
}

在有效的查询中手动编写表达式。然后,反编译程序集(或使用Roslyn online)以查看C#编译器生成的表达式树。这是一个可以使用的模板。发布您尝试过的代码,以便我们可以尝试调整它。在有效的查询中手动编写表达式。然后,反编译程序集(或使用Roslyn online)查看C#编译器生成的表达式树。这是一个可以使用的模板。发布您尝试过的代码,以便我们可以尝试调整它。
 .Lambda #Lambda1<System.Func`2[Model,System.Boolean]>(Model $e) {
.Call ($e.FirstName + " " + $e.LastName + " (" + $e.Code + ")").Contains("Bob")}
Expression expr = GenerateStringConcat(concatArgs[0], concatArgs[1]);
for(int i = 2; i < concatArgs.Count; i++)
    expr = GenerateStringConcat(expr, concatArgs[i]);
private Expression GenerateStringConcat(Expression left, Expression right) {
        return Expression.Call(
             null,
             typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }),
             new[] { left, right });
}
BinaryExpression.Add(concatArgs[0], concatArgs[1])
private Expression GenerateStringConcat(Expression left, Expression right)
{
    return BinaryExpression.Add(left, right, typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }));
}