4

我有一個LINQ-2-Entity查詢生成器,根據相當複雜的搜索表單嵌套不同種類的Where子句。迄今爲止效果很好。實體框架,全文搜索和臨時表

現在我需要在我的一些查詢中使用SQL Server全文搜索索引。是否有機會將搜索詞直接添加到LINQ查詢中,並將分數作爲可選屬性提供?

如果不是,我可以編寫一個存儲過程來加載與全文搜索條件匹配的所有行ID列表,然後使用LINQ-2-Entity查詢加載詳細數據並評估其他可選過濾條件每行一個循環。這當然是一個非常糟糕的主意,在性能方面。

另一種選擇是使用存儲過程將所有匹配全文搜索的行ID插入臨時表中,然後讓LINQ查詢加入臨時表。問題是:如何在LINQ查詢中加入臨時表,因爲它不能作爲實體模型的一部分?

回答

2

我想我可能會提出一種混合方法。

  1. 編寫一個存儲過程,它將返回所需的所有信息。
  2. 將實體映射到結果。該實體可以爲此唯一目的而創建。或者,使用Entity Framework的第4版,它允許映射覆雜類型以啓動過程結果。關鍵是,不是試圖將過程結果強制轉換爲現有的實體類型,而是將它們作爲自己的類型來處理。
  3. 現在您可以構建一個LINQ to Entities查詢。

樣品查詢:

var q = from r in Context.SearchFor("searchText") 
     let fooInstance = (r.ResultType == "Foo") 
      ? Context.Foos.Where(f => f.Id == r.Id) 
      : null 
     where ((fooInstance == null) || (fooInstance.SpecialCriterion == r.SpecialCriterion))  
     select { 
      // ... 

這是從我的頭頂,所以語法可能是不對的。重要的一點是將搜索結果視爲一個實體。

或者:使用更靈活的FTS系統,可以在構建索引時執行「特殊」,每種類型的過濾。

1

我見過這樣的代碼EF4:

var query = context.ExecuteStoreQuery<Person>(
     "SELECT * FROM People WHERE FREETEXT(*,{0})", 
     searchText 
    ).AsQueryable(); 

這可能是比創建在某些情況下,存儲過程或UDP簡單。

+0

這是錯誤的很多方法。 ExecuteStoreQuery返回IEnumerable,所以沒有分頁,沒有真正的.Skip或.Take ... .AsQueryable()只是轉換爲另一種類型。 – Crank 2013-11-27 09:33:47

+0

@Crank,如果你不需要執行DB側跳過/取出或進一步處理,這沒有錯。如果你確實需要這個,那麼你可以修改SQL字符串。如果您有更好的解決方案來實現全文搜索,請提供您自己的答案。 – 2013-11-27 12:56:52

+0

是的,當你不需要做什麼時,你顯然不需要使用它。 好的'LINQ比那好。您可以在表達式樹中使用TVF作爲真正的可查詢... 我們正在嘗試使用真正的Code First支持來找到LINQ替代方案,並且唯一可用的(開放源碼)是流暢的Hibernate和實體框架。 雖然兩者都不如。 EF5不能在代碼第一次定位時正確使用TVF,只能在數據庫中首先使用。你不能把它們組合起來,沒有不必要的麻煩。 – Crank 2013-11-28 13:31:50