2009-02-28 215 views
11

我有一個課程表,我需要根據搜索框中鍵入的關鍵字進行搜索。 下面是一個簡單的查詢:LINQ multiple where子句

SELECT * FROM Courses WHERE 
Title LIKE '%word%' OR Title LIKE '%excel%' OR 
Contents LIKE '%word%' OR Contents LIKE '%excel%' 

我如何轉換這在LINQ其中LINQ將動態生成基於每個關鍵字WHERE語句。

我想用戶PredicateBuilder它工作,只要細如該字段爲VARCHAR。對於「TEXT」字段,不會生成引號,從而導致編譯器給出錯誤消息。下面是PredicateBuilder

SELECT [t0].[CoursesID], [t0].[Title], [t0].[Contents], [t0].[Active], 
FROM [dbo].[Courses] AS [t0] 
WHERE ([t0].[Title] LIKE '%word%') OR ([t0].[Contents] LIKE %word%) OR 
([t0].Title] LIKE '%excel%') OR ([t0].[Contents] LIKE %excel%) 

注意生成的SQL沒有爲「目錄」字段,它是在數據庫中的文本字段中沒有單引號。

有沒有簡單的方法來建立WHERE語句,並查詢重視呢?有沒有人知道我如何在沒有PredicateBuilder的情況下做到這一點?

在此先感謝。

回答

13

既然你工作瓦特/ LINQ我想你是對一個LINQ到SQL數據上下文正確的工作?我沒有備用的DataContext來測試它,但這應該給你一些想法。

雖然我不知道它是否會對數據上下文起作用,但其中大部分都是非常基本的東西(鏈式OR運算符和Contains方法調用),所以在查詢轉換爲SQL時不應引起問題。

首先,我創建一個能夠建立我的謂詞的自定義函數:

Func<string, Func<DataItem, bool>> buildKeywordPredicate = 
    keyword => 
     x => x.Title.Contains(keyword) 
      || x.Contents.Contains(keyword); 

這是接受一個字符串關鍵字,然後返回另一個函數,該函數的DataItem並檢查它針對關鍵字的功能。

基本上,如果你在「堆棧」過去,你會得到一個斷言:x => x.Title.Contains("Stack") || x.Contents.Contains("Stack")

其次,因爲有許多可能的關鍵字,你需要IT連鎖與OR操作,我創建另一個輔助函數鏈與OR

Func<Func<DataItem,bool>, Func<DataItem, bool>, Func<DataItem, bool>> buildOrPredicate = 
    (pred1, pred2) => 
     x => pred1(x) || pred2(x); 

此功能需要2個謂詞,然後2個謂詞一起通過OR操作加入他們。

那些具有2個功能,然後我就可以建立我哪裏謂詞是這樣的:

foreach (var word in keywords) {    
    filter = filter == null 
     ? buildKeywordPredicate(word) 
     : buildOrPredicate(filter, buildKeywordPredicate(word)); 
} 

循環中的第一行基本檢查,如果過濾器爲null。如果是這樣,那麼我們需要爲我們構建一個簡單的關鍵字過濾器。

否則,如果過濾器不爲空,我們需要產業鏈現有的過濾器使用OR操作,所以我們通過現有的過濾器和一個新的關鍵字過濾器buildOrPredicate來做到這一點。

然後我們現在可以創建一個查詢的WHERE部分:

var result = data.Where(filter); 

在我們剛剛建立的複雜謂詞傳遞。

我不知道這是否會與使用PredicateBuilder不同,但由於我們將查詢翻譯推遲到LINQ-to-SQL引擎,所以不應該有任何問題。

但正如我所說的,我沒有對真實的數據上下文進行測試,所以如果有任何問題,您可以在評論中寫下。

下面是我建的測試控制檯應用程序:http://pastebin.com/feb8cc1e

希望這有助於!


編輯:對於其中涉及恰當利用LINQ表達式樹更通用的和可重複使用的版本,看看托馬斯Petricek的博客文章:http://tomasp.net/articles/dynamic-linq-queries.aspx

+1

這將可惜的爲功能才能正常工作。爲了使這個表達式樹的工作,你需要使用這樣的技巧:http://tomasp.net/articles/dynamic-linq-queries.aspx – 2009-03-01 16:55:01

0

作謂語建設者不知道屬性的數據庫類型包含方法被調用,我想這可能是裏面的LINQ to SQL的一個問題。您是否使用普通查詢(而不是使用謂詞構建器)和帶有Contains的TEXT列?