Linq - 从列表中选择项目或默认值

时间:2014-03-05 14:00:37

标签: c# linq

我有一个项目列表,用于存储在SQLite数据库中的字符串本地化。我想检索列表,并使用linq创建项目字典以供显示。如果本地化字符串不存在,那么我想返回默认语言字符串。

示例数据

Item    MetaTag     LanguageCode    Text
1       Hello       en              Hello
1       Hello       fr              Bonjour
1       Hello       de              Guten Tag
1       Goodbye     en              Goodbye

所以如果我想要德语字符串,字典应该包含

1       Hello       de              Guten Tag
1       Goodbye     en              Goodbye

所以我有以下代码:

public interface ILocalisedItem
{
    int ID { get; set; }
    int ItemId { get; set; }
    string MetaTag { get; set; }
    string LanguageCode { get; set; }
}
public class ItemString : ILocalisedItem
{
    int ID { get; set; }
    int ItemId { get; set; }
    string MetaTag { get; set; }
    string LanguageCode { get; set; }
    string Text {get; set; }
}

public static IDictionary<string, T> GetMetaDataDictionary<T>
    (int ItemId, string DisplayLanguage, string DefaultLanguage)
    where T : ILocalisedItem, new()
{

    IEnumerable<T> metadata = GetMetaData<T>(ItemId);

    ILookup<string, T> _lookup = metadata
        .Where(z => (z.LanguageCode == DisplayLanguage) || (z.LanguageCode == DefaultLanguage))
        .OrderBy(x => (x.LanguageCode == DisplayLanguage) ? 0 : 1)
        .ToLookup(o => o.MetaTag);

    return _lookup.ToDictionary(y => y.Key.ToLower(), y => y.First());
}

此代码似乎有效,但我认为必须有更好的方法来执行此操作。任何人都可以帮助提供更好的解决方案。

2 个答案:

答案 0 :(得分:0)

您可以将DefaultIfEmpty与自定义参数一起使用:

ILookup<string, T> _lookup = metadata
        .Where(z => (z.LanguageCode == DisplayLanguage) || (z.LanguageCode == DefaultLanguage))
        .DefaultIfEmpty( defaultLanguage )
        .OrderBy(x => (x.LanguageCode == DisplayLanguage) ? 0 : 1)
        .ToLookup(o => o.MetaTag);

您必须提供变量defaultLanguage

答案 1 :(得分:0)

您可以将声明合并到以下内容:

ILookup<string, T> _lookup = metadata
    .Where(z => (z.LanguageCode == DisplayLanguage) || (z.LanguageCode == DefaultLanguage))
    .OrderBy(x => (x.LanguageCode == DisplayLanguage) ? 0 : 1)
    .GroupBy(x => x.MetaTag)
    .ToDictionary(x => x.ToLower(), y => y.First());

它不是一个清洁剂,但避免额外的查找转换。我认为你拉动和过滤的方法将是提取数据的最有效方法。直接进入字典将第一个操作推送回数据库,但不要引用我。