2011-03-11 71 views
3

玉家伙这是没有意义的......LINQ关键字搜索与包含

我有这样的方法:

// break down the search terms in to individual keywords 
string[] searchTerms = ui_txtSearch.Text.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 
// get the complete list of companies 
List<Company> results = Company.List(); 
// foreach keyword 
for (int i = 0; i < searchTerms.Length; i++) 
{ 
    // results = the existing result set - the items that dont meet the current search term results. 
    results = (from comp in results 
      where comp.Name.Contains(searchTerms[i] 
      select comp).ToList(); 
} 

现在的总体思路是,从公司的名单我想所有包含所有我在ui的文本框中提供的搜索字词中的关键字。

我的问题是这样的“包含” ......如果我在名称字符串说“公司”和我搜索“CO”我期待它作为,因为名称的结果(**上文所强调)将包含但不...

什么想法?

编辑:

好吧,我发现这个问题是区分大小写的,所以我重构代码,以这样的:

// break down the search terms in to individual keywords 
string[] searchTerms = ui_txtSearch.Text.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 
// get the complete list of companies 
List<Company> results = Company.List(); 
// foreach keyword 
for (int i = 0; i < searchTerms.Length; i++) 
{ 
    // results = the existing result set - the items that dont meet the current search term results. 
    results = (
     from comp in results 
     where comp.Name.ToLower().IndexOf(searchTerms[i].ToLower()) > -1 
     select comp 
     ).ToList(); 
} 

为了解决下面一些反馈:

搜索字词可能就像“Test Company 1”一样,我正在寻找所有可以在公司名称中找到“test”和“company”和“1”的结果,并且结果集必须包含所有搜索关键词按“”分割。

做到这一点最干净的方法是使用一个循环按照我的理解??? ...或者我错了吗?

所以我基本上看这是...

  1. 通过搜索词
  2. 过滤列表中得到所有公司名单1
  3. 从搜索项N ...,重复过滤列表过滤
  4. 直到考虑所有条款。
  5. 结果集现在包含在公司名称中提供的所有搜索字词。

当前的代码似乎工作和排序的答案我的问题......但你们认为这是一个更有效的方式来做到这一点?

感谢您的帮助所有:)

编辑2:

感谢所有帮助下面给出我认为最终版本(仍在测试)应该是这样的:

// break down the search terms in to individual keywords 
string[] searchTerms = ui_txtSearch.Text.ToLower().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); 
// get the complete list of companies 
List<Company> results; 
// results = the existing result set - the items that dont meet the current search term results. 
results = (
    from comp in Company.List() 
    where searchTerms.All(s => comp.Name.ToLower().IndexOf(s) > -1) 
    select comp 
    ).ToList(); 

谢谢你大家:)

+0

你应该把这个查询放在循环内部:results = results.where(comp.Name.Contains(searchTerms [i])),并删除“Tolist”。循环后只调用一次.tolist一次。也许它不会解决你的问题,但我认为它是正确的做法。 – Jonathan 2011-03-11 15:42:15

+0

hi jonathon ... ToList调用确保来自每个循环操作的过滤结果始终是类型列表而不是ResultGroup,或者无论linq本身返回什么(它看起来像一个数组列表或字典对象)。此调用可确保在此代码之后查询并最终在我的数据绑定过程中使用相同类型。 – War 2011-03-11 17:00:34

回答

3

你在每次迭代重新分配results。但它也看起来对我来说你可以用这个替换整个代码:

string[] searchTerms = ui_txtSearch.Text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); 

var results = (from comp in Company.List() 
       where searchTerms.All(s => comp.Contains(s)) 
       select comp).ToList(); 

,应该在线路多一点你在找什么。

+0

这就是故意确保在第二次迭代时我只搜索从第一次迭代中传递了linq查询的内容。 – War 2011-03-11 17:08:49

+0

@Wardy:在这种情况下,使用'All()'的上述代码绝对是你想要的。如果你决定使用'for'循环,你最好在循环内使用一个不同于'results'的变量,并且只在最后使用'ToList'。这样,LINQ就可以将所有的'where'子句组合成一个。但是'全部'代码在同一时间可能会做同样的事情,甚至更快。 – 2011-03-11 19:53:04

+0

啊,好的...(上面编辑反映这一点)谢谢你的答案贾斯汀。 – War 2011-03-14 08:26:03

1

在循环中的代码分配的最终结果results,这也是正在搜索的数据。因此,如果Co值是searchTerms中的第二项,它可能不会找到它,因为它在第一次迭代时已被清除。

+0

这是一个好点...但我的最终结果集应包括提供的所有搜索关键字不只是1. – War 2011-03-11 17:01:26

1

“结果”被重新分配在每次迭代,所以结果将是只从阵列中的最后一个搜索项的结果。您还错过了“Contains”方法的结束参数。关闭我的头顶,我说你可能不得不做这样的事情:

  1. 使用不同的列表变量来保存结果(如“finalResults”),并只查询原始列表。 ((linq查询).ToList());我们可以通过下面的代码来创建一个新的列表。

  2. 滤波器具有鲜明的条款最终结果淘汰受骗者

+0

重新分配是故意的,所以我只搜索第二个循环在第一个循环中通过术语比较而不是搜索所有公司数据再次只是然后必须检查哪些是新的。那有意义吗 ? – War 2011-03-11 17:07:41