C# LINQ 中的多词组搜索无法翻译为 SQL
Multi phrase search in C# LINQ Cannot be translated to SQL
我正在尝试编写半高级 LINQ to SQL 查询来搜索我在 .NET 6 项目中的实体。我想让用户能够在搜索中输入类似“用户搜索 a 或替代查找 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。有办法实现吗?
由于 EF Core 不支持对本地集合的查询(Contains
除外),我建议使用 LINQKit,其中包含 PredicateBuilder
.
然后您可以为您的具体情况构建谓词:
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);
我正在尝试编写半高级 LINQ to SQL 查询来搜索我在 .NET 6 项目中的实体。我想让用户能够在搜索中输入类似“用户搜索 a 或替代查找 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。有办法实现吗?
由于 EF Core 不支持对本地集合的查询(Contains
除外),我建议使用 LINQKit,其中包含 PredicateBuilder
.
然后您可以为您的具体情况构建谓词:
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);