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 中不起作用,引发异常