查询嵌套 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 类型的值没有成员值”

“频谱嵌套查询错误” Redshift 错误

LINQ 表达式 - 使用 .Any in s Select 无法翻译

嵌套查询 GraphQL:语法错误 - iOS

嵌套选择MongoDB查询错误

Parse Cloud Code 嵌套查询上的代码 141(错误:未调用成功/错误)