[英]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.