【问题标题】:efcore 3.1 does not support querying with string concatenation?efcore 3.1 不支持字符串连接查询?
【发布时间】:2020-02-26 08:39:32
【问题描述】:

有没有办法通过使用 String.Format 或 $"{}" 或只是传统的 "" + "" + "" 将多个字段连接在一起来使用 EFCore 3.1 进行查询?

我有这个代码:

await this.Db.ACoolDbSet.Where(y => y.Plums + " " + y.Pears == "LOL").ToListAsync();

PlumsPears 是整数。

这会导致这个错误:

System.InvalidOperationException: 'Null TypeMapping in Sql Tree'

这是预期的吗?

This exception was originally thrown at this call stack:
Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.SqlTypeMappingVerifyingExpressionVisitor.VisitExtension(System.Linq.Expressions.Expression)
System.Linq.Expressions.Expression.Accept(System.Linq.Expressions.ExpressionVisitor)
System.Linq.Expressions.ExpressionVisitor.Visit(System.Linq.Expressions.Expression)
Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlBinaryExpression.VisitChildren(System.Linq.Expressions.ExpressionVisitor)
System.Linq.Expressions.ExpressionVisitor.VisitExtension(System.Linq.Expressions.Expression)
Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.SqlTypeMappingVerifyingExpressionVisitor.VisitExtension(System.Linq.Expressions.Expression)
System.Linq.Expressions.Expression.Accept(System.Linq.Expressions.ExpressionVisitor)
System.Linq.Expressions.ExpressionVisitor.Visit(System.Linq.Expressions.Expression)
Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(System.Linq.Expressions.Expression)
Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(System.Linq.Expressions.Expression)
...
[Call Stack Truncated]

添加 y.Plums.ToString() 和 y.Pears.ToString() 解决了这个问题。不幸的是,String.Format 和 $"{}" 仍然无法正常工作

【问题讨论】:

  • 看来问题是因为 y.Plums 和 y.Pears 是整数。添加 y.Plums.ToString() 和 y.Pears.ToString() 解决了这个问题。不幸的是,String.Format 和 $"{}" 仍然无法正常工作。
  • 没有传统的字符串连接,事实上这是一种众所周知的坏习惯。这就是 SQL 注入攻击的发生方式。在这种情况下,虽然表达方式很糟糕。即使 ORM 可以生成正确的查询,服务器 也无法使用索引来加快速度,并且必须扫描整个表。
  • 您应该在问题本身中提及属性类型,并解释实际查询是什么。您发布的内容永远不会是真实的。一个好的查询比较值应该只是Plums==someValue AND Pears=someOtherValue
  • 是的,我完全同意。查询永远不会返回任何内容。但在我看来,它仍然应该在服务器上执行而不会引发错误。附言。谢谢你的信息,@PanagiotisKanavos

标签: c# ef-core-3.1


【解决方案1】:

试试这个

await this.Db.ACoolDbSet.Where(y => y.Plums.ToString() + " " + y.Pears.ToString() == "LOL").ToListAsync();

【讨论】:

  • @PanagiotisKanavos 这确实有效。回答者可能只是添加了一些解释,而不是“试试这个”。
  • @IvanStoev 我没有看到 comment 说属性是整数。在这种情况下,没有理由将它们转换为 strings,只需使用两个 copmarisons 和 AND
  • 我认为这是 EF Core 3 错误。原始表达式映射到String.Concat(object, object)。后者映射到String.Concat(string, string)。显然,他们的新翻译器支持后者,而前者却失败了。
  • @IvanStoev 前者在 SQL 中没有任何意义 - CONCAT 适用于字符串。在使用CONCAT 之前,必须将这些值转换为字符串。如果原版有效,那只是因为客户端评估。
  • @IvanStoev 或者它确实可能是空映射中的错误。如果这些字段中的任何一个具有 NULL 值,CONCAT 将返回 NULL。不过,字符串插值会将 NULL 视为空字符串。那么这里的预期行为是什么?不管是什么,ORM 都窒息了
【解决方案2】:

字符串插值现在在 EF Core 3.1 中工作

await this.Db.ACoolDbSet.Where(y => $"{y.Plums} {y.Pear}" == "LOL").ToListAsync();

【讨论】:

  • 你现在是什么意思? EF 核心 5? 6?
  • @martonx 更新了答案,说它现在在 EF core 3.1 中工作
猜你喜欢
  • 2023-03-05
  • 2021-11-04
  • 1970-01-01
  • 2021-11-09
  • 2018-07-10
  • 2017-12-15
  • 2011-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多