要在实体上实现基本搜索功能,我想检查多个字段中是否至少有一个包含所有提供的搜索词。
为了说明,让我们假设我的实体是一个 Furniture
,有两个名为 Name
和 Description
的字符串字段,我有以下条目我的数据库:
ID | Name | Description
---|----------------|------------
1 | Black chair 1 | Black chair
-> 2 | Red chair 1 | Crimson chair
-> 3 | Red chair 2 | Dark red chair
-> 4 | Black chair 2 | Black straight back chair, red cushion
5 | Blue sofa | Blue sofa
6 | Red sofa | Red sofa
并且我想检索任何字段中包含 red
和 chair
这两个词的所有实体(这里是 2、3 和 4)。
我可以这样写:
var search = new[] { "red", "chair" };
var filtered = _db.Furnitures.AsNoTracking().Where(f => {
search.All(s => f.Name.ToLower().Contains(s))
|| search.All(s => f.Description.ToLower().Contains(s))
});
但是 EF Core 警告我这不能转换为 SQL,并且它将在本地进行评估。
有什么方法可以编写此查询以便在 SQL 中对其进行评估?
注意:这是我面临的问题的简化示例,模型显然很荒谬,所以请不要建议更改我的实体:)
最佳答案
您可以在 LINQ 语句之外创建一些条件作为表达式,然后将它们全部单独应用于您的查询:
var search = new[] { "red", "chair" };
var criteria = search.Select(s => (Expression<Func<Furniture, bool>>)(f => f.Name.ToLower().Contains(s) || f.Description.ToLower().Contains(s)))
.ToList();
var query = criteria.Aggregate(
_db.Furnitures.AsNoTracking().AsQueryable(),
(query, criterion) => query.Where(criterion));
对于更高级的情况(例如 OR
而不是 AND
),您可能需要进行一些表达式树操作,正如我所描述的 here .
var search = new[] { "red", "chair" };
var criteria = search.Select(s => (Expression<Func<Furniture, bool>>)(f => f.Name.ToLower().Contains(s) || f.Description.ToLower().Contains(s)))
.ToList();
var query = _db.Furnitures.AsNoTracking().
.Where(Join(Expression.And, criteria));
关于c# - EF 核心 : where clause to check if at least one string column contains all values in an array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57785577/