Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/30.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#Lambda与分组_C#_Asp.net_Lambda - Fatal编程技术网

c#Lambda与分组

c#Lambda与分组,c#,asp.net,lambda,C#,Asp.net,Lambda,试着用Lambda表达式从数据库中获取数据 假设我有一张有点像这样的桌子(注意空格和大小写): 名称、计数: iPhone 4、15 iphone 4、2 iPhone4、8 如果我尝试按名称查找项(使用StartsWith()),我只想获取计数最高的结果,而不考虑大小写和空格。因此,搜索“iphone4”、“iphone4”都会返回“iphone4”-记录,假设您有一个折叠字符串扩展名,这并不难写。您需要注意的一件事是,不会有从这个到SQL的映射,因此最终的过滤必须在LINQ中完成,直到对象。

试着用Lambda表达式从数据库中获取数据

假设我有一张有点像这样的桌子(注意空格和大小写):

名称、计数:
iPhone 4、15
iphone 4、2
iPhone4、8


如果我尝试按名称查找项(使用StartsWith()),我只想获取计数最高的结果,而不考虑大小写和空格。因此,搜索“iphone4”、“iphone4”都会返回“iphone4”-记录,假设您有一个折叠字符串扩展名,这并不难写。您需要注意的一件事是,不会有从这个到SQL的映射,因此最终的过滤必须在LINQ中完成,直到对象。通过执行部分过滤(例如,在iphone上),然后在内存中完成过滤,您可能可以使DB查询更高效

 db.Table.ToList().Where( t => t.Name.Collapse().StartsWith( searchString.Collapse() )
                  .OrderByDescending( t => t.Count )
                  .Take( 1 );
崩溃在哪里

 public static class StringExtensions
 {
     public static string Collapse( this string source )
     {
          if (string.IsNullOrWhiteSpace( source ))
          {
              return string.Empty;
          }
          var builder = new StringBuilder();
          foreach (char c in source)
          {
              if (!char.IsWhiteSpace( c ))
              {
                  builder.Append( c );
              }
          }
          return builder.ToString();
     }
}

注意:如果可能,最好对数据库进行清理,并且您确实希望这些数据库映射到同一个对象。

如果您有MS Sql Server 2005+版本,以下内容适用于您所述的示例:

var inputString = "iPhone 4";
var token = inputString.ToLower().Replace(" ", "");

var tokenizedQuery = DataContext.Devices.Select(d => new { Device = d, Token = d.Name.ToLower().Replace(" ", "") });
var filteredQuery = tokenizedQuery.Where(d => d.Token == token);
var resultsQuery = filteredQuery.Select(d => d.Device).OrderByDescending(d => d.Count);
var result = resultsQuery.FirstOrDefault();
下面是正在发生的事情:

  • 您正在创建输入字符串的标记化版本,方法是降低输入字符串的大小写,然后删除空格
  • 然后在表上创建一个伪列,以创建一个类似的令牌列
  • 基于此令牌筛选结果
  • 最后,只选择计数最高的记录
  • 但是,您必须意识到,ToLower()和Replace()方法正在转换为在SQL server上运行而不是在应用程序中运行的T-SQL命令。这意味着如果您需要更复杂的标记化例程,或者您不使用MS SQL,这可能不起作用


    正如其他人所指出的,您可能需要稍微清理一下您的设计。实际上,您存储的是一个可以有许多排列的键或搜索关键字。在查询中进行标记化不是可移植的,也不是可执行的,因此理想情况下应该将该字符串的标记化版本存储在它自己的列中。或者,调查一下,因为他们也可能解决您的问题(如果使用MSSQL,同样如此)。

    db.Table.ToList->db.Table.AsEnumerable?谢谢。我明白了。然而,我注意到,如果搜索字符串只是“iphone”,那么“iphone3G”和“iphone3G”的数据库中也可能有记录。在这种情况下,我希望这些记录也以同样的方式分组。我如何修改您的解决方案以满足此要求?@David N-以同样的方式将所有字符串大小写转换为例如所有大写字母进行比较。我的意思是,如果我的数据库包含
    名称,计数:iPhone4、15 iPhone4、2 iPhone4、8 iphone3G、1 iphone3G、10 iphone3G、11
    ,然后我输入一个搜索字符串“iPhone”,我想得到的结果集是
    iPhone4iPhone3G
    ,所以它需要在所有匹配项中取最前面的结果。好吧,我可以理解这个评论。然而,我希望用户能够以他们选择的任何拼写方式引用项目,我正在寻找的是一种呈现最流行拼写的方法(以避免冗余)