2013-03-18 81 views
3

問題陳述修改LINQ查詢

說我有一個查詢,其搜索的人的名字:

var result = (from person in container.people select person) 
      .Where(p => p.Name.Contains(some_criterion) 

這將轉換到包含像子句的SQL查詢:

WHERE NAME LIKE '%some_criterion%' 

這有一些性能影響,因爲數據庫無法有效地使用名稱列上的索引(索引掃描v.s.索引如果我沒有弄錯)。

爲了解決這個問題,我可以決定只StartsWith()來代替,產生使用類似條款就像一個查詢:

WHERE NAME LIKE 'some_criterion%' 

使SQL Server使用的索引查找和成本提供性能一些功能。

我希望能夠爲用戶提供一個選擇:默認使用StartsWith的行爲,但是如果用戶想要使用Contains()進行搜索的「增加的靈活性」,那麼應該使用這個選項。

有什麼我試圖

我以爲這是小事,並繼續實施對字符串的擴展方法。但是,當然,LINQ不接受這個,並拋出異常。

現在,我當然可以去使用if或switch語句併爲每個案例創建一個查詢,但我更願意解決這個問題「更高層次」或更一般化。 簡而言之:由於實際應用程序的複雜性,使用if語句來區分用例是不可行的。這會導致很多重複和混亂。我真的想以某種方式封裝不同的行爲(Contains,StartsWith,EndsWith)。

問題

我應該到什麼地方或者我應該怎麼找?這是與IQueryables組合的情況嗎?我很困惑!

+0

Criterium。單數的標準。 – Oxymoron 2013-03-18 14:08:20

+0

這將是「標準」。 – 2013-03-18 14:08:58

+0

啊哈,好的。沒有意識到。過度規則適用於我自己的語言英語;) – Oxymoron 2013-03-18 14:10:45

回答

8

而不是過於複雜的事情,如何使用if語句?

var query = from person in container.people 
      select person; 

if (userWantsStartsWith) 
{ 
    query = from p in query 
      where p.Name.Contains(some_criterion) 
      select p; 
} 
else 
{ 
    query = from p in query 
      where p.Name.StartsWith(some_criterion) 
      select p; 
} 

更新

如果你真的需要更復雜的東西嘗試尋找LinqKit。它可以讓你做到以下幾點。

var stringFunction = Lambda.Expression((string s1, string s2) => s1.Contains(s2)); 

if (userWantsStartsWith) 
{ 
    stringFunction = Lambda.Expression((string s1, string s2) => s1.StartsWith(s2)); 
} 

var query = from p in container.people.AsExpandable() 
      where stringFunction.Invoke(p.Name, some_criterion) 
      select p; 

我相信這符合您的

要求我真的希望能夠封裝不同的行爲 (包含,StartsWith,的endsWith)不知何故。

+1

哇,我只是寫同樣的...是的,我同意 - 保持簡單 – 2013-03-18 14:10:39

+0

@Doc:+1更簡單 – TalentTuner 2013-03-18 14:12:01

+0

真實的生活查詢是相當巨大的,並與其他幾個人結合,這就像我的問題所述,不是我正在尋找的解決方案 – Oxymoron 2013-03-18 14:12:57

2

您可以在枚舉枚舉之前動態更改查詢。

var query = container.people.AsQueryable(); 

if (contains) 
{ 
    query = query.Where(p => p.Name.Contains(filter)); 
} 
else 
{ 
    query = query.Where(p => p.Name.StartsWith(filter)); 
} 
0

嘗試DIS:

var result = (from person in container.people select person) 
       .Where(p => some_bool_variable ? p.Name.Contains(some_criterium) : p.Name.StartsWith(some_criterium)); 

現實生活中的查詢是相當巨大的,與其他幾個人聯合在一起。這就像我的問題所述,不是我正在尋找的解決方案

Sinse你的查詢是巨大的:你不能只是定義處理所有事情的存儲過程,並調用特定的查詢參數(可能是幾個由main調用的存儲過程,例如按名稱進行em搜索,按age排序的另一個 - 具有不同的排序順序等等以保持代碼清晰)。