如何使用LINQ执行单词搜索?

时间:2015-07-13 12:07:33

标签: c# linq

我有一个包含供应商名称的清单。说

SuppId   Supplier Name
----------------------------------
1        Aardema & Whitelaw
2        Aafedt Forde Gray
3        Whitelaw & Sears-Ewald

使用以下LINQ查询

supplierListQuery = supplierListQuery.Where(x => x.SupplierName.Contains(SearchKey));

我可以在以下条件下正确返回记录,

1)如果我使用搜索字符串" Whitelaw& Sears-Ewald" 它将返回第3记录。

2)如果我使用" Whitelaw" 或" Sears-Ewald" ,它将返回第3条记录。

但是如果我将搜索字符串作为" Whitelaw Sears-Ewald" ,我怎么能返回第3条记录。它总是返回0条记录。

我可以使用ALL来获得此结果,但我不知道如何使用它来满足这一特殊需求。

6 个答案:

答案 0 :(得分:7)

在这种情况下我通常做的是将单词分成一个集合,然后执行以下操作:

var searchopts = SearchKey.Split(' ').ToList();
supplierListQuery = supplierListQuery
    .Where(x => searchopts.Any(y=> x.SupplierName.Contains(y)));

答案 1 :(得分:1)

谢谢大家的快速回复。但是那个有效或轻松解决这个问题的人是蒂莫西克利福德关于此的​​说明。就像他说我改变了我的回答

string[] filters = SearchKey.ToLower().Split(new[] { ' ' });
objSuppliersList = (from x in objSuppliersList
                    where filters.All(f => x.SupplierName.ToLower().Contains(f))
                    select x).ToList();

现在它返回我所有serach条件的结果。

答案 2 :(得分:1)

这对我有用:

IEnumerable<string> keyWords = SearchKey.Split('');

supplierListQuery = supplierListQuery
      .AsParallel()
      .Where
      (
         x => keyWords.All
         (
              keyword => x.SupplierName.ContainsIgnoreCase(keyword)
         )
      );

答案 3 :(得分:0)

您需要使用某种字符串比较器来创建自己的简单搜索引擎,然后您可以找到最有可能包含在结果中的字符串:

public static class SearchEngine
{

    public static double CompareStrings(string val1, string val2)
    {
        if ((val1.Length == 0) || (val2.Length == 0)) return 0;
        if (val1 == val2) return 100;

        double maxLength = Math.Max(val1.Length, val2.Length);
        double minLength = Math.Min(val1.Length, val2.Length);
        int charIndex = 0;
        for (int i = 0; i < minLength; i++) { if (val1.Contains(val2[i])) charIndex++; }

        return Math.Round(charIndex / maxLength * 100);
    }

    public static List<string> Search(this string[] values, string searchKey, double threshold)
    {
        List<string> result = new List<string>();
        for (int i = 0; i < values.Length; i++) if (CompareStrings(values[i], searchKey) > threshold) result.Add(values[i]);
        return result;
    }
}

使用示例:

string[] array = { "Aardema & Whitelaw", "Aafedt Forde Gray", "Whitelaw & Sears-Ewald" };

var result = array.Search("WhitelawSears-Ewald", 80);
// Results that matches this string with 80% or more

foreach (var item in result)
{
   Console.WriteLine(item);
}

输出:Whitelaw & Sears-Ewald

答案 4 :(得分:0)

因为“Whitelaw”出现在两者中,您将获得两个记录。否则没有动态的方法来确定你只想要最后一个。如果你知道你只有这3个,那么追加.Last()来获得最终记录。

supplierListQuery = supplierListQuery.Where(x => x.SupplierName.Contains(SearchKey.Split(' ')[0]));

答案 5 :(得分:-1)

如果您想要一个简单(不是非常方便)的解决方案,

var result = supplierListQuery
                      .Select(x => normalize(x.SupplierName))
                      .Where(x => x.Contains(normalize(SearchKey)));

string normalize(string inputStr)
{
    string retVal = inputStr.Replace("&", "");
    while (retVal.IndexOf("  ") >= 0)
    {
        retVal = retVal.Replace("  ", " ");
    }
    return retVal;
}