2010-09-03 104 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