使用Linq To SQL进行简单搜索

时间:2010-09-03 17:46:05

标签: c# linq-to-sql search search-engine keyword

此查询的问题是什么?如何修复呢?

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 []拆分(Char [])'   没有受支持的SQL翻译。

应该按照每行qKeywords之间的共享字词对结果进行排序,这样您共享的单词越多,您的排名就越高。

感谢。

BTW:如果可以使用Lucene.NET来改进此代码,我很高兴看到一个简短的例子:)

3 个答案:

答案 0 :(得分:2)

  
    

.OrderBy(p =&gt; new List(p.Keywords.Split(''))。

  

嗯,这条消息很清楚。 String.Split()无法转换为SQL。

在单个Linq-to-Sql语句中没有真正好的方法。我建议使用L2S将数据拉出来,将其放入List&lt;&gt;中,然后在那里对它们进行排序。

    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关键字),其中一行用于作业的每个关键字。然后你可以在一个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 :(得分:1)

您可以从SQL-land中检索所有数据并在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)只获得顶部< em> n 条目。

答案 2 :(得分:0)

您无法使用p.Keywords.Split(' ')。 LINQ-to-SQL不支持它。你为什么还要按列表排序呢?