【发布时间】:2021-03-14 20:37:00
【问题描述】:
我们需要在逗号分隔的字符串中搜索给定的术语。构建查询以便它忽略逗号分隔字符串中可能的前导和尾随空格。 我想出了以下查询,它在 EF 6.0 上运行良好
var trimmedTags = tags.Select(t => t.Trim()); // List of tags we need to look for
return products.Where(p => trimmedTags.Any(t => ("," + p.Categories + ",").Contains("," + t + ",")) ||
trimmedTags.Any(t => ("," + p.Categories + ",").Contains(", " + t + ",")) ||
trimmedTags.Any(t => ("," + p.Categories + ",").Contains("," + t + " ,")) ||
trimmedTags.Any(t => ("," + p.Categories + ",").Contains(", " + t + " ,")));
此查询不再在 EF Core 3.1 中运行并引发以下错误:
System.InvalidOperationException: 'The LINQ expression 'DbSet<Product>
.Where(p => __trimmedTags_1
.Any(t => ("," + p.Categories + ",").Contains("," + t + ",")) || __trimmedTags_1
.Any(t => ("," + p.Categories + ",").Contains(", " + t + ",")) || __trimmedTags_1
.Any(t => ("," + p.Categories + ",").Contains("," + t + " ,")) || __trimmedTags_1
.Any(t => ("," + p.Categories + ",").Contains(", " + t + " ,")))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'
我的目标表有数百万行,因此很遗憾无法进行客户评估。 EF Core 团队声称支持string.Contains,但我不明白为什么我的查询在 EF Core 中突然失败。
【问题讨论】:
-
我认为目前最好的办法是迭代
trimmedTags并构建传递给.Where方法的表达式树。您可以生成查询 products.Where(p => "," + p.Categories + ",".Contains(",tag1,") || "," + p.Categories + ",".Contains(", tag2 ,") || "," + p.Categories + ",".Contains(",tag3,"));这应该可以正常工作。 -
自从我使用 EF 以来已经有一段时间了,但是 trimmedTags 上的 ToList(在查询之外)是否解决了问题?或者您可以尝试使用 Ef.Functions.Like 并以某种方式简化比较
-
@dropoutcoder 感谢您的快速跟进。这正是我最终解决问题的方式。您能否将您的评论转换为答案,以便我接受?
-
@IvanStoev 他做到了,在下面一行:)
-
@GETah 似乎有人已经写了答案。我不是在寻找积分。我很乐意提供帮助:)
标签: c# ef-core-3.1