2014-01-06 32 views
3

我使用Linq和Entity Framework Code First首先查詢MS SQL數據庫。要求是能夠對該表運行WHERE SomeColumn LIKE '%sometext'子句。如何更改由linq-to-entities生成的sql?

此,從表面上看,是一個簡單的要求,可以用一個簡單的Linq查詢這樣來完成:

var results = new List<MyTable>(); 
using(var context = new MyContext()) 
{ 
    results = context.MyTableQueryable 
    .Where(x => x.SomeColumn.EndsWith("sometext")) 
    .ToList(); 
} 
// use results 

然而,這不是有效的做法。問題似乎是SomeColumn列不是varchar,而是char(31)。這意味着如果一個字符串保存在少於31個字符的列中,那麼在字符串的末尾會添加空格以確保長度爲31個字符,並且會對.EndsWith()查詢產生影響。

我使用SQL事件探查器來查找從.EndsWith()方法中生成的確切的SQL。以下是我發現:

--previous query code removed for brevity 
WHERE [Extent1].[SomeColumn] LIKE N'%sometext' 

所以很有趣。我不確定在'%sometext'之前N是什麼意思。 (我將在後面google一下。)但我知道,如果我採取相同的查詢,並在SSMS沒有N像這樣運行:

--previous query code removed for brevity 
WHERE [Extent1].[SomeColumn] LIKE '%sometext' 

然後查詢工作正常。有沒有辦法讓Linq和Entity Framework從查詢中刪除N

+1

''N''基本上意味着它將你的字符串視爲一個varchar,這可能是你的問題。 – Kippie

+0

[VARCHAR和NVARCHAR](http://stackoverflow.com/questions/144283/what-is-the-difference-between-varchar-and-nvarchar)。至於你得到的錯誤,它確實看起來很奇怪,而不是我遇到過的問題,但是我再次只在最近的數據庫中使用'NVARCHAR'而沒有問題。 – XN16

+0

@ XN16 - 我更喜歡nvarchar。不幸的是,我不能在這種情況下使用它。 – quakkels

回答

2

請試試這個...

.Where(x => x.SomeColumn.Trim().EndsWith("sometext")) 
+0

oof。謝謝,這工作。現在我需要將'.Trim()'方法寫入我的表達式樹生成器中......呃。我希望能避免這種情況。 :-) – quakkels

+0

@quakkels謝謝.. –

+0

對於那些有興趣的,這會導致以下查詢:'WHERE LTRIM(RTRIM([Extent1]。[SomeColumn]))LIKE N'%sometext'' – quakkels

1

只是跟我的同事誰也有類似的問題,看是否適合你了以下工作:

[Column(TypeName = "varchar")] 
public string SomeColumn 
{ 
    get; 
    set; 
} 

顯然設置類型的列映射將強制查詢將其識別爲VARCHAR,其中字符串通常被解釋爲NVARCHAR

+0

這是打算生成一個列是varchar? (我無法更改現有的數據庫。)或者,這是否意圖導致EF將char(31)列作爲varchar處理? – quakkels

+0

@quakkels我相信這是第二種選擇,它會將其視爲varchar。 – XN16

相關問題