2010-06-08 75 views
0

我遇到了「問題」我不太確定我是否理解實體框架。我正在使用實體框架4,並嘗試使用TDD方法。因此,我最近使用Repository模式實現了一個搜索功能。對於我的測試項目,我正在實現我的存儲庫接口,並有一組「假」對象數據用於測試目的。實體框架和SQL與使用ToLower的對象之間的差異

我遇到了一個問題,試圖讓Contains子句適用於案例不變搜索。我既爲我的測試和對數據庫使用的存儲庫類的代碼片段如下:

if (!string.IsNullOrEmpty(Description)) 
{ 
    items = items.Where(r => r.Description.ToLower().Contains(Description.ToLower())); 
} 

然而,當我跑我的測試情況下,如果我的情況不匹配的基本數據,其中未填充的結果。我嘗試瞭解一下我認爲是一個問題。爲了清楚我的想法,我進行了一次運行,並想知道與EF相同的代碼是否可以用於SQL後端數據庫,因爲SQL將明確支持like命令,並且按照我的預期執行,並使用相同的邏輯。

我明白爲什麼EF對數據庫後端支持Contains子句。但是,我很驚訝我的單元測試沒有。任何想法爲什麼除了SQL服務器支持類似子句時,我使用的是對象而不是數據庫服務器?

謝謝!

約翰

回答

4

LINQ to Entities和LINQ to Objects具有不同的規則。就這麼簡單。例如,在LINQ到實體,我可以運行這樣的查詢:

var foo = Context.Foos.Where(f => f.Bar.Something == bar); 

...如果f.Bar恰好是一個空引用,這句話仍然會工作得很好,因爲f.Bar.Something將合併到null 。如果您考慮SQL的工作方式,使用LEFT JOIN,這應該不會令人驚訝。另一方面,在LINQ到對象中,相同的Where表達式會拋出一個空引用異常。

正如您發現的,還有其他方面的差異。區分大小寫是一個。當執行LINQ to Entities查詢時,它將轉換爲SQL。根據數據庫中定義的歸類規則以及SQL執行相等比較。要爲數據庫自定義排序規則,通常需要爲列選擇特定排序規則。另一方面,爲了自定義對象的排序規則,通常需要傳遞一個比較函數,這在LINQ to Entities中永遠不會被接受,因爲函數(而不是表達式)不能轉換爲SQL。

有,然而,一個辦法做到不區分大小寫的比較,這兩個LINQ提供程序的工作原理:

var foo = Context.Foos.Where(f => f.SomeString.Equals(someValue, StringComparison.OrdinalIgnoreCase));