簡體   English   中英

Linq 搜索多列多詞搜索詞

[英]Linq search multiple columns with multiple word search term

我正在撓頭如何實現這一目標

我有一張產品和變體表。

假設我的產品表中有一條名為Sony Monitor的記錄

在我的變體表中,我有一個相關變體,其 VariationName 為32"

如果我構造我的 linq 如下:

var productSearch = products.Where(p => p.Name.Contains(searchTerm) || p.Variation.Name.Contains(searchTerm)

“Sony”會產生一個搜索結果。 32"將產生搜索結果。

Sony 32"不會產生搜索結果。

實現這一目標的最佳方法是什么?

編輯

為了便於使用,我為我的搜索結果創建了一個 ViewModel (ProductSearch)。 我將“匹配”添加為 integer 字段。

我連接我的產品和變體表以獲取結果列表。 我遇到問題的代碼如下:

string searchTerm = "Sony 32";
            string[] searchTerms = searchTerm.Split(' ');
            //Concat my two queries (this works fine without the new search code)
            var productSearch = rootProducts.Concat(variableProducts)
                .OrderBy(p => p.Name)
                .Select(p => new ProductSearch()
                {
                    InternalSku = (string)p.InternalSku,
                    ProductId = (int)p.ProductId,
                    ProductVariationId = (int?)p.ProductVariationId,
                    Name = (string)p.Name,
                    ManufacturerSku = (string)p.ManufacturerSku,
                    Ean = (string)p.Ean,
                    ImageUrl = p.ImageUrl,
                    WebDisplay = (bool)p.WebDisplay,
                    VariationName = (string)(p.Name),
                    Matches =
            new[] { p.Name, p.VariationName }
                .SelectMany(x => searchTerms, (x, y) => x.Contains(y))
                .Count(),
                })
                .Skip(skip)
                .Take(take)
                .ToList();

我收到的錯誤是:

無法翻譯 LINQ 表達式“x”。 以可翻譯的形式重寫查詢,或通過插入對“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的調用顯式切換到客戶端評估。

史蒂夫,

我認為答案在某種程度上取決於您的數據所在的位置。 一般來說,

var productSearch = products.Where(p => searchTerm.Contains(p.Name) || searchTerm.Contains(p.Variation.Name))

應該管用。 如果您使用 LINQ 到 SQL 或 LINQ 到實體,事情可能會開始變得有點混亂,因為其中一些技術不支持string.contains

最后,您可能最終不得不執行以下操作:

var productSearch = products.Where(p => searchTerm.Any(x => p.Name.Contains(searchTerm)) || 
    searchTerm.Any(z => p.Variation.Name.Contains(searchTerm)));

簡單的。 嘗試這個:

var searchText = "Sony 32";
var searchTerms = searchText.Split(' ');

var productSearch =
    products
        .Select(p => new
        {
            product = p,
            matches =
                new[] { p.Name, p.Variation.Name }
                    .SelectMany(x => searchTerms, (x, y) => x.Contains(y))
                    .Count(),
        })
        .Where(x => x.matches >= 1)
        .OrderByDescending(x => x.matches)
        .Select(x => x.product)
        .ToArray();

這會嘗試在搜索詞和您正在搜索的元素之間找到盡可能多的匹配項,首先為您提供最多的匹配項,然后至少有一個匹配項。

您可能需要添加一些.ToLowerInvariant()調用以允許不區分大小寫的搜索。


嘗試此變體以首先將數據加載到 memory 中。

var productSearch =
    products
        .Select(p => new { p.Name, Variation = p.Variation.Name })
        .ToArray()
        .Select(p => new
        {
            product = p,
            matches =
                new[] { p.Name, p.Variation }
                    .SelectMany(x => searchTerms, (x, y) => x.Contains(y))
                    .Count(),
        })
        .Where(x => x.matches >= 1)
        .OrderByDescending(x => x.matches)
        .Select(x => x.product)
        .ToArray();

暫無
暫無

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

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