查询嵌套 Any() 翻译错误
Posted
技术标签:
【中文标题】查询嵌套 Any() 翻译错误【英文标题】:Query with nested Any() translation error 【发布时间】:2021-12-07 15:42:55 【问题描述】:我正在尝试编写一个半高级的 LINQ to SQL 查询来搜索我在 .NET 6 项目中的实体。我的 LINQ 语句中的过滤看起来像这样:
List<string> _searchList = new() "%a%", "%b%";
var _query = (from tblHeader in _DbContext.batches
where tblHeader.isDeleted != true
select tblHeader)
_query = _query.Where(x =>
_searchList.All(y =>
EF.Functions.Like(x.Name, y)
)
);
var _results = await _query.ToListAsync();
错误看起来像:
The LINQ expression 'y => __Functions_1
.Like(
matchExpression: EntityShaperExpression:
FFM.DataAccessModels.App.batches
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
.Name,
pattern: y)' 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 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
是否可以在 Where() 中使用 LINQ All()(甚至是 linq Any())?或者有没有更好的方法来编写这个查询?
【问题讨论】:
对于这个查询,你可以遍历搜索列表并多次执行 Where (它将加入你的 where 条件和)。 LINQ to Entities 仅在使用本地集合时支持Contains
。使用this my solution,它将创建所需的SQL。
@Evk 这是我当前的解决方案,但是我正在尝试合并能够进行 OR 搜索(即搜索“用户输入 A”或“替代用户输入 B”),匹配每个单词在搜索 1 或搜索 2 中的每个单词。这样,我想要的查询还包含另一个嵌套的 .All() 运算符,但在我的问题中,我将其简化为 if first 开始中断的位置。
遗憾的是,没有“内置”支持。您需要手动创建表达式,但您可以使用一些第三方库,例如 LinqKit
@Evk 有没有什么方法可以将这种 OR 功能与您最初建议的循环结合起来?
【参考方案1】:
因为您想要的解决方案是 _searchList 中与查询匹配的所有项目都可以使用循环对 _searchList 中的每个项目使用 Where
子句重写,结果仍然是单个查询。
List<string> _searchList = new() "%a%", "%b%";
var _query = _DbContext.batches.Where(x => !x.isDeleted);
foreach(var searchItem in _searchList)
_query = _query.Where(x => EF.Functions.Like(x.Name, searchItem);
var _results = await _query.ToListAsync();
【讨论】:
这里的问题 - 如何进行 OR。 您必须使用您在回答中描述的表达式树来执行 OR,但是我正在回答所提出的问题。【参考方案2】:使用this我对扩展方法FilterByItems
的回答。然后您可以执行以下操作:
List<string> _searchList = new() "%a%", "%b%";
var _query =
from tblHeader in _DbContext.batches
where tblHeader.isDeleted != true
select tblHeader;
_query = _query
.FilterByItems(_searchList, (x, y) => EF.Functions.Like(x.Name, y), true);
var _results = await _query.ToListAsync();
【讨论】:
@Svyatslav Danyliv 这个解决方案效果很好。现在假设我有一个要搜索的短语变量列表,而不仅仅是单数单词(即搜索“用户输入 A”或“替代用户输入 B”或“第三输入搜索”,而不是“a”或“乙”)。我想匹配任何一个短语中的每个单词。可以扩展它来处理这种情况吗? 在这种情况下,您必须使用PredicateBuilder
,您可以从 LINQKit 中提取它,或者只添加 NuGet 包。如果您想要一个示例,请创建另一个问题。
一个样本会很棒!我发布了一个新问题here【参考方案3】:
你不能这样做吗?
var result = _DbContext.batches
.Where(tblHeader => tblHeader.isDeleted != true)
.Where(x => _searchList.All(y => EF.Functions.Like(x.Name, y))
.ToListAsync();
编辑:
like查询支持wildcards,我想你需要匹配所有包含'a'和'b'的结果,所以你可以使用:“[ab]%”。
var result = _DbContext.batches
.Where(tblHeader => tblHeader.isDeleted != true)
.Where(x => EF.Functions.Like(x.Name, "[ab]%"))
.ToListAsync();
【讨论】:
以上是关于查询嵌套 Any() 翻译错误的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3 / 如何处理嵌套的 NSDictionaries,因为“Any 类型的值没有成员值”