c# - EF 核心 : where clause to check if at least one string column contains all values in an array

标签 c# entity-framework-core

要在实体上实现基本搜索功能,我想检查多个字段中是否至少有一个包含所有提供的搜索词。

为了说明,让我们假设我的实体是一个 Furniture,有两个名为 NameDescription 的字符串字段,我有以下条目我的数据库:

    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

并且我想检索任何字段中包含 redchair 这两个词的所有实体(这里是 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/

相关文章:

c# - 暂停一个新的 BackGroundWorker 直到上一个完成

c# - 如何将文件大小解析为字符串

c# - Linq.Select() 中的嵌套表达式方法调用

c# - 如何删除 Entity Framework .Core 中的一组记录?

asp.net-core - 无法使用单例中的作用域服务 applicationdbcontext

entity-framework-core - EF Core 迁移错误 : Database 'MyDatabaseName' already exists. 选择不同的数据库名称

c# - 如何设置多对多关系,实体的不同关系状态可能会有所不同

c# - CellStyle 意外应用于工作表中的所有单元格 - NPOI?

c# - 使用 Windows 身份验证对单个操作而不是整个应用程序进行身份验证

c# - 创建或寻找 fuslogvw.exe 的替代品,又名 Fusion Assembly Binding Log Viewer