2013-01-09 39 views
2

好吧,這種行爲讓我真的難倒了。我有一個IQueryable列表,我試圖添加Where子句來檢查字符串字段是否包含子字符串。當我硬編碼這樣的搜索字符串:添加Linq問題包含字符串的Where子句包含測試

sourceList = sourceList.Where(license => license.FileNumber.Contains("S0")) 

它能正常工作,並從Visual Studio調試器檢查SOURCELIST產生內部查詢:

{SELECT [Extent1].[id] AS [id], [Extent1].[FileNumber] AS [FileNumber], 
    [Extent1].[LegalLocation] AS [LegalLocation]FROM [dbo].[Licenses] 
    AS [Extent1]WHERE [Extent1].[FileNumber] LIKE N'%S0%'} 

奇怪的事情發生時,我設置了搜索從值的變量,如:

string testString = "S0"; 
sourceList = sourceList.Where(license => license.FileNumber.Contains(testString)) 

這產生內部查詢:

{SELECT [Extent1].[id] AS [id], [Extent1].[FileNumber] AS [FileNumber], 
    [Extent1].[LegalLocation] AS [LegalLocation]FROM [dbo].[Licenses] 
    AS [Extent1]WHERE [Extent1].[FileNumber] LIKE @p__linq__0 ESCAPE N'~'} 

注意最後LIKE部分的區別?我很困惑。任何幫助將不勝感激。希望這真的很愚蠢。如果它有任何相關性,這是爲了過濾來自實體框架源的數據。

感謝, 傑森

+2

它在第二種情況 – horgh

+0

是否第二個查詢返回不正確的結果或出現其他不必要的行爲只是通過像參數? – phoog

+0

我不認爲它會返回正確的結果,但實際上是由一個無關的問題引起的。我接受了Brad的解決方案,因爲它是最詳細的。感謝大家! – Jason

回答

1

如果觀察實際的查詢,你會看到@p__linq__0實際分配S0值,然後傳遞給查詢。

@p__linq__0 = '%S0%'; 
... WHERE [Extent1].[FileNumber] LIKE @p__linq__0 ESCAPE N'~' 

這基本上是這樣的:

... WHERE [Extent1].[FileNumber] LIKE N'%S0%' ESCAPE N'~' 

而且因爲它是一個參數,LINQ只是需要的注意事項,並增加了ESCAPE條款。它也是一個變量,而不是一個硬編碼常量,並且LINQ語句中的任何更改值都作爲參數傳遞,而不是直接插入到查詢中。

參考:LIKE (Transact-SQL)

+0

你絕對是對的布拉德,這只是顯示我的新手狀態,當談到Linq :) – Jason

1

第二內部查詢只使用一個參數的LIKE子句中,如所預期。

如果你觀察到不同的結果,可能是因爲你在一個情況下通過"SO",在另一個情況下通過"S0"(至少在你的問題的一些代碼中)。

+0

'S0'和'SO':很好的捕獲 – horgh

+0

雖然這不是我混亂的原因,當我測試它實際上都是S0。儘管爲了清楚起見,我已在我的帖子中修復了它。謝謝! – Jason

1

在第二種情況下,LINQ生成一個參數化查詢。想想,如果你constrcuted參數化查詢使用一些DbCommand手動:

OleDbCommand cmd = new OleDbCommand(
    "SELECT * from SomeTable where SomeField like @Param1", con); 
cmd.Parameters.Add("@Param1", OleDbType.VarChar).Value = "%SomeField value%"; 

所以@p__linq__0是LINQ生成的參數的名稱(而在我的例子是@Param1)。

ESCAPE關鍵字是LIKE表達式的一部分(見LIKE (Transact-SQL)):

語法

match_expression [ NOT ] LIKE pattern [ ESCAPE escape_character ] 

其中

ESCAPE_CHARACTER

Is a character that is put in front of a wildcard character to indicate that the  
wildcard should be interpreted as a regular character and not as a wildcard. 
escape_character is a character expression that has no default and must evaluate to 
only one character.