Как Группе Несколько использований Объектов GroupBy ()?

Рассмотрите следующие упрощенные объекты и отношения:

public class Job{
  int JobId;
  String name;
  String status;
  Discipline disc;
  WorkCategory workCat;
}

public class Discipline {
  int DisciplineId;
  String DisciplineName;
}

public class Workcategory{
   int WorkCategoryId;
   String WorkCategoryName;
}

public Class Grouping{
   Discipline parent;
   List<Workcategory> children;
}

Вышеупомянутые модели отношения это a Job связан с одним Discipline и один WorkCategory. Workcategory всегда ребенок определенного родителя Discipline (связь "один ко многим"). Мы можем предположить, что отношения присвоенного Discipline и Workcategory всегда будут допустимы.

Проблема, с которой я сталкиваюсь, - когда я пытаюсь создать a Grouping объект результата на основе фильтров, к которым относятся Jobs. Я не уверен, Может ли это быть сделано или если подход, который я проявляю, даже корректен. Сам точный вопрос не ясен мне, однако вышеупомянутое определяет проблемный оператор.

  1. Дизайн может быть улучшен?
  2. Как я могу сгруппировать Задания Discipline и Workcategory?
  3. Сделайте мне даже нужно Grouping класс?

Я попробовал следующее (это - мое первое использование попытки Linq), но ни к какому успеху, поскольку мое понимание не достаточно полно. Другая альтернатива должна сначала добраться Discipline группа и цикл посредством исходной группировки, берущей связанное Workcategory.

var grouping = repository.GetJobsWithActiveStatus()
            .GroupBy(x => new {
                                  x.Discipline.DisciplineID, 
                                  x.Discipline.DisciplineName,  
                                  x.Category.WorkCategoryID, 
                                  x.Category.WorkCategoryName
                              })
            .Select(g => new Grouping{
                                 Discipline = new Discipline{
                                                  DisciplineID = g.Key.DisciplineID, 
                                                  Name = g.Key.DisciplineName
                                                  }, 
                                 Categories = ?? // this is where I am lost
                             }});

Править: Отправив это, я понял, что параметры inital GroupBy приводят к одной группе объекта, тогда как я ищу результат Подгруппы Группы.

Редактирование 2: Для разъяснения немного далее я не хочу связанного Jobs как часть результата, а скорее группировку Дисциплины-Workcategory - таким образом причина Grouping класс


Начальное решение на основе @Obalix

Редактирование 7 марта 2010:

Это решение не работает - GroupBy на объектной Дисциплине приведет к уникальной группировке для каждого объекта. Я думаю, что это происходит из-за него являющийся ссылочным типом. Я корректен? Я первоначально принял это как ответ, однако после того, как некоторое царапание головы поняло, что мои ложные данные сами были дефектными. Начальные вопросы все еще остаются отвеченными.

var result = repository.GetJobsWithActiveStatus()
      .GroupBy(x => x.disc)
      .Select(g => new Grouping
              {
                  Discipline = g.Key,
                  Catergories = g.GroupBy(x=>x.workCat) // <--- The Problem is here, grouping on a reference type
                                 .Select(l=>l.Key) // needed to select the Key's only
                                 .ToList()
              });
6
задан Ahmad 7 March 2010 в 06:32
поделиться

4 ответа

Вот описание того, как можно реализовать механизм иерархического группирования.

Общий способ сделать это с помощью LINQ (как показано в ссылке):

var list = new List<Job>();

var groupedList = list.GroupBy(x => x.disc)
    .Select(g => new {
        Key = g.Key,
        Count = g.Count(),
        WorkCategoryGroups = g.GroupBy(x => x.workCat)
    });

Однако ссылка также описывает альтернативный способ, который позволяет вам сделать следующее:

var groupedList = list.GroupByMany(x => x.disc, x => x.workCat);

Изменить: Следуя указаниям Ахмада комментарий здесь - строго типизированная версия:

var groupedList = list.GroupBy(x => x.disc)
    .Select(g => new Grouping {
        parent = g.Key,
        children = g.GroupBy(x => x.workCat).ToList()
    });
2
ответ дан 17 December 2019 в 07:03
поделиться

Вот еще один способ, который не требует класса группирования.

ILookup<Discipline, Workcategory> result = repository
  .GetJobsWithActiveStatus()
  .Select(job => new {disc = job.disc, workCat = job.workCat})
  .Distinct()
  .ToLookup(x => x.disc, x => x.workCat);
0
ответ дан 17 December 2019 в 07:03
поделиться

Я бы использовал синтаксис Linq:

var jobsByDiscipline = 
    from j in repository.GetJobsWithActiveStatus()
    group j by j.Discipline.DisciplineID into g
    select new { 
        DisciplineID = g.Key,
        Jobs = g.ToList() 
    };

var jobsByCategory = 
    from j in repository.GetJobsWithActiveStatus()
    group j by j.Workcategory.WorkcategoryID into g
    select new { 
        WorkcategoryID = g.Key,
        Jobs = g.ToList() 
    };

Я считаю это легче читать, чем множество связанных методов с параметрами лямбда-функции.

Вы можете получить свои группы из этого:

var disciplineAndCategory = 
    from j in repository.GetJobsWithActiveStatus()
    group j by j.Discipline.DisciplineID into g
    let categories = 
        from j2 in g
        select j2.Workcategory.WorkcategoryID
    select new { 
        DisciplineID = g.Key,
        Jobs = categories.Distinct() // each category id once 
    };
2
ответ дан 17 December 2019 в 07:03
поделиться

Вот решение, которое работает для меня.

Сначала мне нужно было получить все группы дисциплин, затем создать связанные списки рабочих категорий. где идентификаторы дисциплин равны.

var result = liveJobs
.GroupBy(x => new {
               x.disc.DisciplineID, 
               x.disc.DisciplineName
                  })
.Select(g => new Grouping()
              {
               parent = new Discipline(g.Key.DisciplineID,g.Key.DisciplineName),
               children = g.Where(job=>job.disc.DisciplineID == g.Key.DisciplineID) // filter the current job discipline to where the group key disciplines are equal
              .Select(j=>j.workCat)
              .ToList()
              });
0
ответ дан 17 December 2019 в 07:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: