c # лямбда и группировка - PullRequest
       4

c # лямбда и группировка

0 голосов
/ 29 августа 2011

пытаюсь разобраться, используя лямбда-выражения для извлечения данных из моей базы данных.

Скажем, у меня есть таблица, которая выглядит примерно так (обратите внимание на пробелы и регистр):

имя, количество:
iPhone 4, 15
iphone 4, 2
iPhone4, 8

Если я пытаюсь найти элементы по имени (используя StartsWith ()), я хочу получить результат только с наибольшим количеством, независимо от регистра и пробелов. Поэтому поиски «iphone4», «i p h o 4», «iPhone4» должны все возвращать запись «iPhone 4»

Ответы [ 2 ]

1 голос
/ 29 августа 2011

Если у вас 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();

Вот что происходит:

  1. Вы создаететокеновую версию вашей входной строки, поместив ее в нижний регистр и затем удалив пробелы.
  2. Затем вы создаете псевдостолбец в своей таблице, чтобы создать аналогичный столбец токенов
  3. Фильтруйте результаты на основеэтот токен
  4. Наконец, выберите только запись с наибольшим количеством

Однако очень важно, чтобы вы понимали, что методы ToLower () и Replace () переводятся в T-Команды SQL, которые выполняются на сервере sql , а не в вашем приложении.Это означает, что если вам нужны более сложные подпрограммы токенизации, или вы не используете MS SQL , это может не сработать!

Как уже отмечали другие, вы, возможно, захотите немного очистить свой дизайн.По сути, вы храните ключевое слово или ключевое слово для поиска, которое может иметь много перестановок.Выполнение токенизации в запросе не является переносимым или производительным, поэтому в идеале вы должны хранить токенизированную версию этой строки в своем собственном столбце.В качестве альтернативы посмотрите полнотекстовые индексы , так как они могут также решить вашу проблему (опять же, если используется MSSQL).

0 голосов
/ 29 августа 2011

Давайте предположим, что у вас есть расширение строки Свернуть, которое нетрудно написать. Одна вещь, которую вы заметите, состоит в том, что не будет сопоставления этого с SQL, поэтому окончательная фильтрация должна быть выполнена в LINQ to Objects. Возможно, вы сможете сделать запрос к БД более эффективным, выполнив частичную фильтрацию (т.е. на iphone), а затем завершите фильтрацию в памяти.

 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();
     }
}

Примечание: вам лучше очистить базу данных, если это возможно, и вы действительно хотите, чтобы они соответствовали одной и той же вещи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...