2011-02-04 39 views
0

我想在LINQ中翻譯這個查詢......如果我們在純SQL中執行它,但是在動態創建的LINQ查詢中(構建基於用戶輸入的搜索查詢),這是非常容易的,它是一個全新的故事。在LINQ中翻譯此查詢? (列表相似)

SELECT * FROM MyTable 
WHERE 1=1 
    AND Column2 IN (1,2,3) 
    AND (Column1 LIKE '%a%' OR Column1 LIKE '%b%') 

我們試圖建立這樣我們試圖這樣說:

if(myOjb.Column2Collection != null) 
    query = query.where(f => f.Column2.Contains(myOjb.Column2Collection)); 

if(myObj.Column1Collection != null) 
{ 
    // tough part here ? 
    //query = query.Where(); ... 
} 

那麼,什麼是最好的形式給出這個正常?

注意,我知道SqlMethod.Like的,儘管我不明白的方式來實現在這裏吧...

+0

'WHERE 1 = 1`的用途是什麼?這不僅僅意味着「真實」,並且不會有所作爲? – Marcus 2011-02-04 14:49:20

+6

@G_M - 通常這是在構建動態SQL時完成的,因此您不需要繼續檢查現有的where子句。 – Oded 2011-02-04 14:50:17

+0

是你的問題如何動態地處理OR? – JohnOpincar 2011-02-04 15:28:21

回答

0

嘗試是這樣的:

var colums2 = { 1, 2, 3 }; 
var result = (from o in myOjb 
       where columns2.Any(co2 => co2 == o.Column2) 
       && Column1.Contains(column2valueA) 
       || Column1.Contains(column2valueB) 
       select o); 

希望能幫助

0
var sc = StringComparison.OrdinalIgnoreCase; 
var col2Values = new int[] { 1, 2, 3 };  

var query = from item in myObj 
      where col2Values.Contains(item.Column2) 
      && (item.Column1.IndexOf("a", sc) >= 0 
       || item.Column1.IndexOf("b", sc) >= 0) 
      select item; 

我還沒有測試過,但它的構建就好了。原始版本,如果上面的失敗:

var col2Values = new int[] { 1, 2, 3 }; 

var query = from item in myObj 
      let col1 = item.Column1.ToLower() 
      where col2Values.Contains(item.Column2) 
      && (col1.Contains("a") || col1.Contains("b")) 
      select item; 

其實我更喜歡第二個版本,即使是慢稍微因爲ToLower()的。在我看來,閱讀起來更容易。因人而異。

0
from o in myObj 
where 
new[] { 1, 2, 3 }.Contains(o.Column2) && 
new[] { "a", "b" }.Any(s => o.Column1.IndexOf(s, StringComparison.Ordinal) != -1) 
select o; 

或使用new Hashset<T>如果你關心查找性能。數組只帶來O(n)。


Ordinal意味着Unicode比較字節每字節沒有特定的文化問題,最快捷。

OrdinalIgnoreCase意味着相同,但大小寫敏感

1

爲了得到Like ..或者Like ..等等,我認爲你必須編寫自己的擴展來爲你構建表達式樹。我想做到這一點前一陣子,結束了在計算器上這裏找到一個不同的文章:Linq to Sql any keyword search query

從那裏,我想你會這樣寫:

string[] terms = new string[] {"a", "b"} 
query = query.LikeAny(table => table.Column1, terms) 

順便說一句,你還可以在更改代碼鏈接頁面做的,而不是或改變

var body = conditions.Aggregate((acc, c) => Expression.Or(acc, c)); 

var body = conditions.Aggregate((acc, c) => Expression.And(acc, c)); 

這是我當時想要的,叫它LikeAll