簡體   English   中英

EF Core:where 子句檢查是否至少一個字符串列包含數組中的所有值

[英]EF Core: where clause to check if at least one string column contains all values in an array

要在實體上實現基本搜索功能,我想檢查多個字段中是否至少有一個包含所有提供的搜索詞。

為了說明這一點,讓我們假設我的實體是一個具有兩個名為NameDescription字符串字段的Furniture ,並且我的數據庫中有以下條目:

    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 ),您可能需要進行一些表達式樹操作,正如我在此處所述。

    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));

有什么辦法可以編寫此查詢,以便在 SQL 中對其進行評估?

最好的選擇是使用您自己編寫的原始查詢

沒有什么比使用原始查詢從 SQL 數據庫中選擇數據更快或更靈活了。 它准確地為您提供所需的內容,並避免在運行時處理和翻譯表達式的開銷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM