【问题标题】:Multi phrase search in C# LINQ Cannot be translated to SQLC# LINQ 中的多短语搜索无法转换为 SQL
【发布时间】:2026-01-11 15:45:02
【问题描述】:

我正在尝试编写一个半高级的 LINQ to SQL 查询来搜索我在 .NET 6 项目中的实体。我想让用户能够在搜索中输入类似“用户搜索或替代查找 b 或来自 joe 的单独查询”之类的内容。处理用户输入后,我的 LINQ 查询设置如下:

bool isNameSearch = true;
bool isNoteSearch = true;

List<List<string>> _multiSearchList = new()
{
    new List<string>() { "user", "search", "a" },
    new List<string>() { "alternative", "lookup", "b" },
    new List<string>() { "seperate", "query", "from", "joe" }
};


 var _query = (from tblHeader in _DbContext.batches
               where tblHeader.isDeleted != true
               select tblHeader)

_query = _query.Where(x => 
    _multiSearchList.Any(y =>
        y.All(z => 

        (isNameSearch && x.Name.Contains(z)) ||
        (isNoteSearch && x.Note.Contains(z))

        )
    )
);

var _results = await _query.ToListAsync();
var _totalCount = await _query.CountAsync();

问题是,虽然这个查询可以和本地集合一起工作,但它不能被翻译成 sql。有没有办法做到这一点?

【问题讨论】:

  • 实际样本不正确。没有_multiSearchList 用法。
  • @SvyatoslavDanyliv 已修复!

标签: c# linq entity-framework-core linq-to-entities


【解决方案1】:

由于 EF Core 不支持使用本地集合进行查询(Contains 除外),我建议使用具有 PredicateBuilderLINQKit

然后你可以为你的具体情况构建谓词:

bool isNameSearch = true;
bool isNoteSearch = true;

List<List<string>> _multiSearchList = new()
{
    new List<string>() { "user", "search", "a" },
    new List<string>() { "alternative", "lookup", "b" },
    new List<string>() { "seperate", "query", "from", "joe" }
};


var _query = (from tblHeader in _DbContext.batches
               where tblHeader.isDeleted != true
               select tblHeader)

var mainPredicate = PredicateBuilder.New(_query);
foreach (var sentense in _multiSearchList)
[
    var predicate = PredicateBuilder.New(_query);

    foreach(var word in sentense)
    [
        var subPredicate = PredicateBuilder.New(_query);
    
        if (isNameSearch)
            subPredicate = subPredicate.Or(x => x.Name.Contains(word));
        if (isNoteSearch)
            subPredicate = subPredicate.Or(x => x.Note.Contains(word));

        predicate = predicate.And(subPredicate)
    ]

    mainPredicate = mainPredicate.Or(predicate);
]

_query =  _query.Where(mainPredicate);

【讨论】: