2012-03-02 2 views
0

У меня есть фрагмент кода, который я хотел бы сократить, используя Linq. Речь идет о части цикла foreach(), которая выполняет дополнительную группировку в результирующем наборе и строит вложенный Dictionary.Сложный цикл foreach можно сократить до linq?

Можно ли использовать более короткий 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:

Что в основном происходит, что «тексты» для каждого языка и для каждого свойства для определенного OBJECTTYPE (в данном случае HARDCODED 1) выбраны и сгруппированы по языку. Словарь словарей создается для каждого языка, а затем для каждого свойства.

Entities имеют свойство под названием Texts (словарь словарей). Apply является пользовательский метод расширения, который выглядит следующим образом:

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

Вы можете использовать 'метод расширения .Foreach' перебрать' yy' с помощью лямбда-выражения. Кроме того, я считаю, что лучше выполнять группировку перед 'q.ToList();'. кроме того, использование * BETTER NAMING *! –

+0

Вы правы в названии, я просто озадачился и продолжал писать лямбды, что я сошел с ума от сущности, текста и просто хотел набрать x, y, z :). – ReFocus

+0

Однако может ли запрос группы linq быть выполнен внутри .ToDictionary каким-то образом? – ReFocus

ответ

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 и текста не имеют типа в вашем коде, так что я назвал мои типы после имен ...

Смежные вопросы