使用 'and' 运算符的 Linq 搜索文本
Linq search text using 'and' operator
我在下表中有一对多关系
产品 [ProductId, Name(varchar)]
关键字 [KeywordId, 关键字(varchar)]
KeywordsToProducts[Id, ProductId, KeywordId]
假设搜索文本是 "blue pro"。我需要使用运算符 'and' 搜索这两个关键字。
如果我执行以下操作:
string test="blue pro";
string[]words = test.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var query = from p in Products
join kp in KeywordsToProducts on p.ProductId equals kp.ProductId
join kw in Keywords on kp.KeywordId equals kw.KeywordId
where (words.All(x=>kw.Keyword.Contains(x)))
那我什么也没有得到,因为字段关键字只包含一个词。
如何加入 'Keywrods.Keyword' 数据库字段记录以便使用 'and' 运算符进行搜索?
如果您加入每个匹配的 KeywordsToProducts
到 Keywords
,您可以将它们收集起来并进行比较:
var query = from p in Products
join kp in KeywordsToProducts on p.ProductId equals kp.ProductId into kpj
let kws = (from kp in kpj join kw in Keywords on kp.KeywordId equals kw.KeywordId select kw.Keyword)
where words.All(w => kws.Any(kw => kw.Contains(w)))
select p;
但是,我认为如果先分别执行 KeywordsToProducts
到 Keywords
join
会更容易理解(并且可能更有效率)(注意它显示了连接table 最好命名为 KeywordIdsToProductIds
):
var kwToProducts = from kp in KeywordsToProducts
join kw in Keywords on kp.KeywordId equals kw.KeywordId
select new { kp.ProductId, kw.Keyword };
var query = from p in Products
join kwp in kwToProducts on p.ProductId equals kwp.ProductId into kwpj
where words.All(w => kwpj.Any(kwp => kwp.Keyword.Contains(w)))
select p;
虽然我(不一定)喜欢提及它,但还要注意 EF 导航属性可以隐藏连接 table 并使此查询更容易。
它会是这样的:
var query = from p in Products
where words.All(w => p.Keywords.Any(k => k.Contains(w)))
select p;
我假设您打算使用 String.Contains
以便用户可以输入部分关键字并仍然找到匹配项。如果你想要求所有的关键字都匹配,这里是相同的代码:
var query = from p in Products
join kp in KeywordsToProducts on p.ProductId equals kp.ProductId into kpj
let kws = (from kp in kpj join kw in Keywords on kp.KeywordId equals kw.KeywordId select kw.Keyword)
where words.All(w => kws.Contains(w))
select p;
拆分子连接:
var kwToProducts = from kp in KeywordsToProducts
join kw in Keywords on kp.KeywordId equals kw.KeywordId
select new { kp.ProductId, kw.Keyword };
var query = from p in Products
join kwp in kwToProducts on p.ProductId equals kwp.ProductId into kwpj
where words.All(w => kwpj.Select(kwp => kwp.Keyword).Contains(w))
select p;
EF 导航属性:
var query = from p in Products
where words.All(w => p.Keywords.Contains(w))
select p;
我在下表中有一对多关系
产品 [ProductId, Name(varchar)]
关键字 [KeywordId, 关键字(varchar)]
KeywordsToProducts[Id, ProductId, KeywordId]
假设搜索文本是 "blue pro"。我需要使用运算符 'and' 搜索这两个关键字。 如果我执行以下操作:
string test="blue pro";
string[]words = test.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
var query = from p in Products
join kp in KeywordsToProducts on p.ProductId equals kp.ProductId
join kw in Keywords on kp.KeywordId equals kw.KeywordId
where (words.All(x=>kw.Keyword.Contains(x)))
那我什么也没有得到,因为字段关键字只包含一个词。
如何加入 'Keywrods.Keyword' 数据库字段记录以便使用 'and' 运算符进行搜索?
如果您加入每个匹配的 KeywordsToProducts
到 Keywords
,您可以将它们收集起来并进行比较:
var query = from p in Products
join kp in KeywordsToProducts on p.ProductId equals kp.ProductId into kpj
let kws = (from kp in kpj join kw in Keywords on kp.KeywordId equals kw.KeywordId select kw.Keyword)
where words.All(w => kws.Any(kw => kw.Contains(w)))
select p;
但是,我认为如果先分别执行 KeywordsToProducts
到 Keywords
join
会更容易理解(并且可能更有效率)(注意它显示了连接table 最好命名为 KeywordIdsToProductIds
):
var kwToProducts = from kp in KeywordsToProducts
join kw in Keywords on kp.KeywordId equals kw.KeywordId
select new { kp.ProductId, kw.Keyword };
var query = from p in Products
join kwp in kwToProducts on p.ProductId equals kwp.ProductId into kwpj
where words.All(w => kwpj.Any(kwp => kwp.Keyword.Contains(w)))
select p;
虽然我(不一定)喜欢提及它,但还要注意 EF 导航属性可以隐藏连接 table 并使此查询更容易。
它会是这样的:
var query = from p in Products
where words.All(w => p.Keywords.Any(k => k.Contains(w)))
select p;
我假设您打算使用 String.Contains
以便用户可以输入部分关键字并仍然找到匹配项。如果你想要求所有的关键字都匹配,这里是相同的代码:
var query = from p in Products
join kp in KeywordsToProducts on p.ProductId equals kp.ProductId into kpj
let kws = (from kp in kpj join kw in Keywords on kp.KeywordId equals kw.KeywordId select kw.Keyword)
where words.All(w => kws.Contains(w))
select p;
拆分子连接:
var kwToProducts = from kp in KeywordsToProducts
join kw in Keywords on kp.KeywordId equals kw.KeywordId
select new { kp.ProductId, kw.Keyword };
var query = from p in Products
join kwp in kwToProducts on p.ProductId equals kwp.ProductId into kwpj
where words.All(w => kwpj.Select(kwp => kwp.Keyword).Contains(w))
select p;
EF 导航属性:
var query = from p in Products
where words.All(w => p.Keywords.Contains(w))
select p;