【问题标题】:Linq search text using 'and' operatorLinq 使用“和”运算符搜索文本
【发布时间】:2017-08-04 21:16:01
【问题描述】:

我在下表中有一对多的关系

产品 [ProductId, Name(varchar)]

关键字 [KeywordId, Keyword(varchar)]

KeywordsToProducts[Id、ProductId、KeywordId]

假设搜索文本是“blue pro”。我需要使用运算符“和”搜索这两个关键字。 如果我执行以下操作:

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”运算符进行搜索?

【问题讨论】:

    标签: linq search operator-keyword


    【解决方案1】:

    如果您将每个匹配的 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;
    

    但是,我认为如果您先分别执行 KeywordsToProductsKeywords join 会更容易理解(并且可能更有效)(请注意,它显示连接表会更好地命名为 @987654328 @):

    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 导航属性可以隐藏连接表并使此查询更容易。

    应该是这样的:

    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;
    

    【讨论】:

    猜你喜欢
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 2022-11-13
    • 1970-01-01
    • 1970-01-01
    • 2011-10-31
    • 2013-09-11
    相关资源
    最近更新 更多