复杂的foreach循环可能缩短到linq?

时间:2012-03-02 18:17:06

标签: linq lambda

我想用Linq缩短我想要缩短的代码。它是关于foreach()循环中对结果集执行额外分组并构建嵌套Dictionary的部分。

这是否可以使用较短的Linq语法?

        var q = from entity in this.Context.Entities
                join text in this.Context.Texts on new { ObjectType = 1, ObjectId = entity.EntityId} equals new { ObjectType = text.ObjectType, ObjectId = text.ObjectId}
        into texts
                select new {entity, texts};

        foreach (var result in q)
        {
            //Can this grouping be performed in the LINQ query above?
            var grouped = from tx in result.texts
                    group tx by tx.Language
                    into langGroup
                    select new
                               {
                                   langGroup.Key,
                                   langGroup
                               };
            //End grouping

            var byLanguage = grouped.ToDictionary(x => x.Key, x => x.langGroup.ToDictionary(y => y.PropertyName, y => y.Text));

            result.f.Apply(x => x.Texts = byLanguage);
        }

        return q.Select(x => x.entity);

Sideinfo:

基本上发生的是,每种语言的“文本”和特定对象类型的每个属性(在本例中为硬编码的1)都是按语言选择和分组的。为每种语言创建字典字典,然后为每个属性创建。

Entities有一个名为Texts的属性(词典词典)。 Apply是一种自定义扩展方法,如下所示:

    public static T Apply<T>(this T subject, Action<T> action)
    {
        action(subject);
        return subject;
    }

1 个答案:

答案 0 :(得分:2)

这不是更简单吗?

foreach(var entity in Context.Entities)
{
   // Create the result dictionary.
   entity.Texts = new Dictionary<Language,Dictionary<PropertyName,Text>>();

   // loop through each text we want to classify
   foreach(var text in Context.Texts.Where(t => t.ObjectType == 1 
                                             && t.ObjectId == entity.ObjectId))
   {
       var language = text.Language;
       var property = text.PropertyName;

       // Create the sub-level dictionary, if required
       if (!entity.Texts.ContainsKey(language))
           entity.Texts[language] = new Dictionary<PropertyName,Text>();

       entity.Texts[language][property] = text;
   }
}

有时好的旧foreach循环可以更好地完成工作。

语言,PropertyName和Text在您的代码中没有类型,因此我在名称后命名了我的类型...