Простой поиск с Linq To SQL - PullRequest
       11

Простой поиск с Linq To SQL

3 голосов
/ 03 сентября 2010

В чем проблема с этим запросом и как я могу исправить это?

public JsonResult Find(string q)
{
    var k = new List<string>(q.Split(' '));

    return Json(_dataContext.Jobs
        .OrderBy(p => new List<string>(p.Keywords.Split(' ')).Where(n => k.Contains(n)).Count())
        .Select(p => new { p.Title, p.IsFullTime, p.Location, p.Category, p.Url, p.Id }),
        JsonRequestBehavior.AllowGet);
 }

Выдает:

Метод 'System.String [] Split (Char [])' не поддерживает перевод на SQL.

Предполагается упорядочить результаты по общим словам между q и Keywords для каждогопоэтому, чем больше вы поделились словами, тем выше ваш заказ.

Спасибо.

КСТАТИ: Если возможно использовать Lucene.NET для улучшения этого кода, ябыл бы рад увидеть короткий пример:)

Ответы [ 3 ]

2 голосов
/ 03 сентября 2010

.OrderBy (p => новый список (p.Keywords.Split ('')).

Ну, сообщение совершенно ясно. Строка.Split () нельзя перевести на SQL.

Нет действительно хорошего способа сделать это в одном операторе Linq-to-Sql. Я бы предложил вытащить данные с помощью L2S, поместить их вПеречислите <>, а затем отсортируйте их там.

    var jobs  = from p in _dataContext.Jobs
    select new 
      {
        p.Title,
        p.IsFullTIme,
        p.Location,
        p.Category,
        p.Url,
        p.Id,
        p.Keywords
      }

      return Json(job.ToList()
            .OrderBy(p=>p.Keywords.Split(' ').Where(n=>k.Contains(n)).Count()),
             JsonRequestBehavior.AllowGet);

Однако ваша реальная проблема заключается в том, что у вас действительно плохой дизайн. В правильной третьей нормальной форме будет таблица JobKeywords (int JobId, varchar Keyword)с одной строкой для каждого ключевого слова для работы. Тогда вы можете сделать это одним оператором sql:

 return Json(from p in _dataContext.Jobs     
             order by p.Keywords.Intersect(k).Count()
             select new { p.Title, p.IsFullTime, p.Location, 
                          p.Category, p.Url, p.Id },     
        JsonRequestBehavior.AllowGet);            
1 голос
/ 03 сентября 2010

Вы можете извлечь все данные из SQL-земли и выполнить разбиение строк в C # -land:

public JsonResult Find(string q)
{
    var k = q.Split(' ');

    return Json(_dataContext.Jobs
        // Select all the columns we need, including Keywords
        // (still in SQL-land)
        .Select(p => new { p.Title, p.IsFullTime, p.Location, p.Category,
                           p.Url, p.Id, p.Keywords })
        // Move into C#-land
        .AsEnumerable()
        // Do the sorting here in C#-land
        .OrderBy(p => p.Keywords.Split(' ').Count(n => k.Contains(n)))
        // Finally, remove the Keywords column we no longer need
        .Select(p => new { p.Title, p.IsFullTime, p.Location, p.Category,
                           p.Url, p.Id }),
        JsonRequestBehavior.AllowGet);
 }

Однако, это будет медленно, потому что будет извлекать вся Таблица заданий каждый раз, даже если вы добавляете .Take(n) в конце, чтобы получить только верхние n записей.

0 голосов
/ 03 сентября 2010

Вы не можете использовать p.Keywords.Split(' '). LINQ-to-SQL не поддерживает это. И вообще, почему вы заказываете список?

...