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