LINQ / EF Core 不能在查询中使用 string.Contains

Posted

技术标签:

【中文标题】LINQ / EF Core 不能在查询中使用 string.Contains【英文标题】:LINQ / EF Core cannot use string.Contains in query 【发布时间】:2021-05-03 05:12:06 【问题描述】:

在我看来,这应该很简单: 我有一个字符串列表,我只想返回 db 行,其中该列与列表中包含的所有字符串匹配。

例如,如果我的字符串搜索查询是 "R", "E", "I" ,它应该返回 MyStringColumn 列中包含字母 R、E 和 I 的所有记录(以任何顺序)。

代码示例:

var reiks = new List<string>  "R", "E", "I" ;
var result = _context.MyTable.Where(x => reiks.All(r => x.MyStringColumn.Contains(r)));

不幸的是,这会返回以下错误:

System.InvalidOperationException。 LINQ 表达式 '数据库集() .Where(c => __reiks_0 .All(r => c.MyStringColumn.Contains(r)))' 无法翻译。要么以可翻译的形式重写查询,要么切换 通过插入对“AsEnumerable”的调用来明确地进行客户评估, “AsAsyncEnumerable”、“ToList”或“ToListAsync”。

如果我像这样重写代码,它可以工作,但这只是一个临时解决方案,因为我不能保证只有 3 个字符串:

var result = _context.MyTable.Where(x => ((reiks.Count == 0 || x.MyStringColumn.Contains(reiks[0])) && (reiks.Count <= 1 || x.MyStringColumn.Contains(reiks[1])) && (reiks.Count <= 2 || x.MyStringColumn.Contains(reiks[2]))));

我做错了什么?我还尝试了使用 Any 而不是 All 的第一个代码示例,但无论哪种方式都不起作用。

【问题讨论】:

这是因为All 没有与任何SQL 子句匹配,所以EF 无法为您生成SQL。 @CodeNotFound 翻译此代码的替代方法是什么?它不应该与 Any() 一起使用吗? 另一种方法是创建一个存储过程,它将接收 reiks 列表作为参数并将结果映射到您的实体。向数据库服务器发送大查询的性能要高得多。 @TimGerhard 想想那个查询的等效 SQL 是什么,如果你仍然认为翻译器应该能够做到这一点。也许构造一个等效的 SQL 查询会给你一个不同的 Linq 等效? 【参考方案1】:

你可以像这样分解条件:

var reiks = new List<string>  "R", "E", "I" ;
var query = _context.MyTable.AsQueryable();
foreach(var reik in reiks)

    query = query.Where(x => x.MyStringColumn.Contains(reik));

var result = query.ToList();

【讨论】:

【参考方案2】:

Try this:

var result = _context.MyTable.AsEnumerable()
                             .Where(x => reiks.All(r => x.MyStringColumn.Contains(r)));

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于LINQ / EF Core 不能在查询中使用 string.Contains的主要内容,如果未能解决你的问题,请参考以下文章

使用 LINQ 查询语法 EF Core C# 的左外连接

比较 EF Core Linq 查询中的 DateTime

LINQ 实体框架查询在 EF Core 中不起作用,引发异常

EF Core 多对多关系上的 LINQ 查询

EF Core 嵌套 Linq 选择导致 N + 1 个 SQL 查询

使用 linq 计算 EF Core 中的平均评分