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