2010-09-03 70 views
3

什么是问题与此查询,我怎么能修复它?简单的搜索与Linq To SQL

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 []斯普利特(字符[])' 没有支持转换为SQL。

它应该让你有更多共享的话,你是有序的更高qKeywords的每一行之间的共有词排序的结果。

谢谢。

BTW:如果可以使用Lucene.NET改善这个代码,我高兴地看到一个简单的例子:)

+0

无关你的问题:你不需要'新名单'无处不在。你可以直接使用'Split'的结果。 – Timwi 2010-09-03 17:52:35

回答

2

.OrderBy(P =>新的列表(第.Keywords.Split(”“))。

那么,所述消息是faily清楚。String.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关键字),其中一行为,每个作业的关键字。然后,您可以在一条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);    
0

您不能使用p.Keywords.Split(' ')。 LINQ-to-SQL不支持它。而且你为什么要按名单订购?

1

你可从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); 
} 

然而,这是怎么回事,因为它会检索整个是缓慢的Jobs表中的每一次,即使您在末尾添加.Take(n)以获取仅顶部n条目。

+0

原来也要返回整个Job表。 – 2010-09-03 18:00:58

+1

'AsEnumerable'只返回相同的列表。没有在'IQueryable'上定义的操作。您需要使用ToList(或朋友)来进行实际检索。然而,'AsEnumerable'确实允许从SQL到.NET的转换在后续的调用中进行,因为参数是代表。 – leppie 2010-09-03 18:13:42

+0

@Ieppie:你说得对,'AsEnumerable()'实际上并不检索,但我认为这并不重要。当然不需要列表。 – Timwi 2010-09-03 18:21:08