2010-08-03 95 views
1

例如,我有一個表存儲特定鍵的文化變體。LINQ問題 - 查詢

 
RecordID Key CultureID Description 
1   1  en-GB  Hour 
2   1  es-ES  hora 
3   2  en-GB  Swimming 

我有這個作爲一個IEnumerable鑑於我想返回以下@ CultureID = 「ES-ES」 的paremeter。簡而言之,如果存在文化變體,則返回給定參數,否則返回「en-GB」條目(哪些Allways存在)。有人可以幫我用這個LINQ查詢。

 
RecordID Key CultureID Description 
2   1  es-ES  hora 
3   2  en-GB  Swimming 

感謝

+0

我假設這是LINQ到SQL,而不是LINQ到對象?或者按表格來表示內存中的數據結構? – Jacob 2010-08-03 17:01:15

回答

0

我認爲你將不得不作出兩個查詢。一個嘗試獲取文化變體的值(使用SingleOrDefault()),然後檢查返回的值是否爲空。如果是,則使用en-BG而不是給定的參數作爲參數進行相同的查詢。

var result = (from i in records where RecordID = 1 && CultureID = "es-ES" select i).SingleOrDefault(); 

if (result == null) result = = (from i in records where RecordID = 1 && CultureID = "es-ES" select i).Single(); 

或者可能使用一些orderby子句?

1

總有另一種方式。

聯盟:

IEnumerable<Varriant> result = variants 
    .Where(x=>x.CultureID == CultureID) 
    .Union(variants.Where(x=> x.CultureID == "en-GB")) 
.ToList(); 

Variant v = variants.FirstOrDefault(); 

其他

IEnumerable<Varriant> result = (
    from x in variants 
     where x.CultureID == CultureID || x.CultureID == "en-GB" 
    select x 


).ToList(); 

Varriant r = null; 
if(result.Length <= 1){ 
    r = result.FirstOrDefault(); 

}else{ 
    r = result.First(x=>x.CultureID !="en-GB"); 
} 
2

您可以使用一個事實,即布爾值排序爲[假的,真],因此下面的查詢將整理所有匹配先等於en-GB,然後等於en-GB

var result = (from x in variants 
       where x.CultureID == cultureID || x.CultureID == "en-GB" 
       orderby x.CultureID == "en-GB" 
       select x).First(); 

如果甚至沒有什麼「EN-GB」項存在一個給定鍵此查詢會給出錯誤(First要求至少一個),但正如你所說,它始終存在。如果您不確定,請使用FirstOrDefault

請注意,很多LINQ提供者都支持這種習慣用法,它不僅僅適用於IEnumerable/Lists。因此,您甚至可以將鍵和文化上的過濾器結合爲LINQ查詢的一部分,因此您可以讓數據庫爲您進行分類,並且不會獲得整個翻譯列表,只需要您想要的那個:

var result = (from x in db.Translations 
       where x.Key == someKey 
       && (x.CultureID == cultureID || x.CultureID == "en-GB") 
       orderby x.CultureID == "en-GB" 
       select x).First(); 
+0

我喜歡那樣!假設它有效;)。 – Nix 2010-08-03 15:40:47

+0

這是如何轉換爲SQL?只是感興趣。 – Nix 2010-08-03 16:53:44

+0

我已經測試過實體框架和Linq-to-SQL,並且這兩個框架都支持這種查詢。它基本上轉化爲'CASE WHEN x.CultureID ='en-GB'THEN 1 ELSE 0 END'。所以要小心如果你想爲大型中間套裝做到這一點。在這裏你知道你只會在你的WHERE中匹配幾條記錄,但是如果你試圖用這種方式來分割你的排序順序,那麼你可能沒有找到合適的索引。我不知道這個問題的一般解決方案,因爲聯盟可能不是非常高效。預先計算的列(例如IsCatchAllTranslation BIT)可能可能有用。 – Ruben 2010-08-03 17:03:14