Entity Framework 使用 Concat 的核心 LINQ 树表达式问题
Entity Framework Core LINQ Tree Expression Problem with Concat
所以我有一个 IQueryable 扩展,它的功能比这段代码多一点。本质上,我是在组合一堆字符串,然后对它们执行 Contains。我 运行 遇到的问题是 Entity Framework Core 不支持 System.String.Concat,并在本地执行那部分查询,这绝对不是我想要的。
这是我用来将这些不同的字符串加在一起的小循环:
List<Expression> stringExpressionsToConcat = new List<Expression>();
foreach (var member in memberExpressions)
{
stringExpressionsToConcat.Add(member);
stringExpressionsToConcat.Add(spaceConstant);
}
//call the concat to create the final term to search on
NewArrayExpression arrayExpression = Expression.NewArrayInit(typeof(string), stringExpressionsToConcat);
searchStringExpression = Expression.Call(concatMethod, arrayExpression);
这是工作的客户端,但不会为实体编译到 SQL。我在 Order By 子句上遇到了同样的问题,我正在做这样的事情:
.ThenByDescending(e => string.Concat(e.FirstName, " ", e.LastName))
这显然也没有转换为 SQL 的实体,因为它正是我在表达式树中构建的内容。然而,把它改成这个....
.ThenByDescending(e => e.FirstName + " " + e.LastName)
将实体转换为 SQL。所以我想知道如何创建上面代码中表示的相同表达式,并正确发送到 SQL。我试过使用 Expression.Add 但表达式构建器中的字符串类型不支持添加。这是可能的还是 Entity Framework 中有一些额外的代码使这成为可能?我试图探索 GitHub 上的源代码,但要找到它发生的确切位置有点让人不知所措。
基本上:等待 EfCore 在某个时候支持它,或者现在使用 Ef classic。
EfCore 对 LINQ 的支持非常有限 - 感觉有点像开发它的人从未使用过它,也从未阅读过 LINQ 可以提供的所有内容。没有解决方法。
在 EfCore 2.2 中,它正在进行客户端评估 - 在 3.1 中被禁用,它会告诉您去进行不同的编程。
如果您愿意,请在 github 页面上打开一个问题,然后也许有人会在 11 月 5.0 版中选择它。机会是没有的,因为这有点神秘,而且他们有很多更常见的问题。
啊哈!我想通了!!此表达式树表现出相同的行为并将数据发送到 SQL!
修改后的代码:
//more than one member has the property, we need to combine them with spaces in between
List<Expression> stringExpressionsToConcat = new List<Expression>();
foreach (var member in memberExpressions)
{
stringExpressionsToConcat.Add(member);
stringExpressionsToConcat.Add(spaceConstant);
}
searchStringExpression = stringExpressionsToConcat[0];
for (int i = 1; i < stringExpressionsToConcat.Count; i++)
{
searchStringExpression = Expression.Add(searchStringExpression,
stringExpressionsToConcat[i], typeof(string).GetMethod("Concat", new[] {
typeof(string), typeof(string) }));
}
该更改从 Entity Framework 抛出 2.2 中的警告(以及 3.1 中的错误)到将其转换为以下 SQL 代码!
([e].[MemberExpression1] + N' ') + [e].[MemberExpression2]) + N' ') + [e].[MemberExpression3]) + N' ')
这正是 Entity Framework 生成 SQL 子句的方式,我在对 Order By 的回答中谈到了!我不确定推理是什么......但是,如果你想创建自己的表达式树,将 Entity Framework 核心树访问者可以翻译成 sql 的字符串加在一起,这是它!
感谢这个答案为我指明了正确的方向:
所以我有一个 IQueryable 扩展,它的功能比这段代码多一点。本质上,我是在组合一堆字符串,然后对它们执行 Contains。我 运行 遇到的问题是 Entity Framework Core 不支持 System.String.Concat,并在本地执行那部分查询,这绝对不是我想要的。
这是我用来将这些不同的字符串加在一起的小循环:
List<Expression> stringExpressionsToConcat = new List<Expression>();
foreach (var member in memberExpressions)
{
stringExpressionsToConcat.Add(member);
stringExpressionsToConcat.Add(spaceConstant);
}
//call the concat to create the final term to search on
NewArrayExpression arrayExpression = Expression.NewArrayInit(typeof(string), stringExpressionsToConcat);
searchStringExpression = Expression.Call(concatMethod, arrayExpression);
这是工作的客户端,但不会为实体编译到 SQL。我在 Order By 子句上遇到了同样的问题,我正在做这样的事情:
.ThenByDescending(e => string.Concat(e.FirstName, " ", e.LastName))
这显然也没有转换为 SQL 的实体,因为它正是我在表达式树中构建的内容。然而,把它改成这个....
.ThenByDescending(e => e.FirstName + " " + e.LastName)
将实体转换为 SQL。所以我想知道如何创建上面代码中表示的相同表达式,并正确发送到 SQL。我试过使用 Expression.Add 但表达式构建器中的字符串类型不支持添加。这是可能的还是 Entity Framework 中有一些额外的代码使这成为可能?我试图探索 GitHub 上的源代码,但要找到它发生的确切位置有点让人不知所措。
基本上:等待 EfCore 在某个时候支持它,或者现在使用 Ef classic。
EfCore 对 LINQ 的支持非常有限 - 感觉有点像开发它的人从未使用过它,也从未阅读过 LINQ 可以提供的所有内容。没有解决方法。
在 EfCore 2.2 中,它正在进行客户端评估 - 在 3.1 中被禁用,它会告诉您去进行不同的编程。
如果您愿意,请在 github 页面上打开一个问题,然后也许有人会在 11 月 5.0 版中选择它。机会是没有的,因为这有点神秘,而且他们有很多更常见的问题。
啊哈!我想通了!!此表达式树表现出相同的行为并将数据发送到 SQL!
修改后的代码:
//more than one member has the property, we need to combine them with spaces in between
List<Expression> stringExpressionsToConcat = new List<Expression>();
foreach (var member in memberExpressions)
{
stringExpressionsToConcat.Add(member);
stringExpressionsToConcat.Add(spaceConstant);
}
searchStringExpression = stringExpressionsToConcat[0];
for (int i = 1; i < stringExpressionsToConcat.Count; i++)
{
searchStringExpression = Expression.Add(searchStringExpression,
stringExpressionsToConcat[i], typeof(string).GetMethod("Concat", new[] {
typeof(string), typeof(string) }));
}
该更改从 Entity Framework 抛出 2.2 中的警告(以及 3.1 中的错误)到将其转换为以下 SQL 代码!
([e].[MemberExpression1] + N' ') + [e].[MemberExpression2]) + N' ') + [e].[MemberExpression3]) + N' ')
这正是 Entity Framework 生成 SQL 子句的方式,我在对 Order By 的回答中谈到了!我不确定推理是什么......但是,如果你想创建自己的表达式树,将 Entity Framework 核心树访问者可以翻译成 sql 的字符串加在一起,这是它!
感谢这个答案为我指明了正确的方向: