2013-09-07 2 views
0

Мне сложно найти правильный запрос Linq для использования вывода группы.Как практически назначить повторяющиеся объекты из групп

Я хочу, чтобы заполнить существующий студентов Список, где класс Student имеет 2 свойства ID и и ИНТ [] Повтор массив (может быть список тоже), чтобы сколько раз они взяли любой из 4 лекции (L101, L201, L202, L203). Так что, если студент принимает L101 дважды, L202 и L203 один раз, и, но не принимать L201 это должно быть {2,0,1,1}

class Student{ 

    public string ID{get;set;} 
    public int[] Repeats{get;set;} //int[0]->L101, int[1]->L201... 
} 

В моем главном классе я эту основную операцию для этого Задача:

foreach (var student in students) 
{ 
    var countL101 = from s in rawData 
        where student.Id==s.Id & s.Lecture =="L101" 
        select; //do for each lecture 

    student.Repeats = new int[4]; 
    student.Repeats[0] = countL101.Count(); //do for each lecture 
} 

Это работает; но мне интересно, как вы делаете это практически с помощью Linq в случае, если есть 100 лекций?

+0

Позвольте мне знать, если я сделал неверные предположения о ' rawData' и т. д., и я отредактирую свой ответ. – blins

ответ

0

Я использую Lamba Expressions, а не синтаксис запроса. Тогда при условии rawData является IEnumerable<T> где T выглядит как ...

class DataRow 
{ 
    /// <summary> 
    /// Id of Student taking lecture 
    /// </summary> 
    public string Id { get; set; } 
    public string Lecture { get; set;} 
} 

Тогда вы могли бы сделать что-то вроде ...

var lectures = rawData.Select(x => x.Lecture).Distinct().ToList(); 
int i = 0; 
lectures.ForEach(l => 
{ 
    students.ForEach(s => 
     { 
      if (s.Repeats == null) 
       s.Repeats = new int[lectures.Count]; 

      s.Repeats[i] = rawData.Count(x => x.Id == s.Id && x.Lecture == l); 
     }); 
    i++; 
}); 

Теперь, если Repeats может быть просто типа IList<int> вместо int[] тогда. ..

var lectures = rawData.Select(x => x.Lecture).Distinct().ToList(); 
lectures.ForEach(l => 
{ 
    students.ForEach(s => 
    { 
     if (s.Repeats == null) 
      s.Repeats = new List<int>(); 

     s.Repeats.Add(rawData.Count(x => x.Id == s.Id && x.Lecture == l)); 
    }); 
}); 

Вещи далее упрощаются, если Repeats может просто быть создан, чтобы в Student конструктор нового List<int> ...

class Student 
{ 
    public Student() 
    { 
     Repeats = new List<int>(); 
    } 
    public string Id { get; set; } 
    public IList<int> Repeats { get; private set; } 
} 

Тогда вы можете сделать это в одной строке ...

rawData.Select(x => x.Lecture).Distinct().ToList() 
    .ForEach(l => 
    { 
     students.ForEach(s => 
     { 
      s.Repeats.Add(rawData.Count(x => x.Id == s.Id && x.Lecture == l)); 
     }); 
    }); 
+0

Это то, что я называю prctical способом! Спасибо blins, да данные строки имеют строки Id и Lecture. Я попробовал третий вариант, и он работает. Интересно, хотя; с предположением, что существует несколько месяцев этих лекций, и каждый месяц имеет переменную понесенную стоимость, mCost в rawData; нормально ли я включаю SelectMany (x => x.Lecture, y => y.Month) в отличии и аналогично Repeats, если мы хотим заполнить s.FailCosts.Add(), как мы суммируем ежемесячные затраты? – invictus

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