Как группировать по нескольким полям?

432
04 мая 2017, 11:23

Пример кода взят из MSDN. В нем показано,как получить сумму ,группируя по одному полю.

`// Fill the DataSet.
DataSet ds = new DataSet();
ds.Locale = CultureInfo.InvariantCulture;
FillDataSet(ds);
DataTable orders = ds.Tables["SalesOrderHeader"];
var query =
    from order in orders.AsEnumerable()
    group order by order.Field<Int32>("ContactID") into g
    select new
    {
        Category = g.Key,
        TotalDue = g.Sum(order => order.Field<decimal>("TotalDue")),
    };
`

Мне нужно группировать по нескольким полям . Как это можно сделать? Привожу свой код ,как я это использую :

 private void button1_Click_1(object sender, EventArgs e)
    {
        var  regi = (from r in db.Registrs.ToList()
                   group r by  r.company into g
                   //group r by r.city into f
                   select new
                  {
                       Date = checkBox1.Checked ?  g.Key : null,                           
                       Company = checkBox2.Checked ? g.Key : null,
                       City = checkBox3.Checked ? g.Key : null,                                         
                       Country = checkBox4.Checked ? g.Key : null,
                       Manager = checkBox5.Checked ? g.Key : null,
                       Quantity = checkBox1.Checked || checkBox2.Checked || checkBox3.Checked || checkBox4.Checked || checkBox5.Checked ? g.Sum(s => s.quantity) : null,
                       Amount = checkBox1.Checked || checkBox2.Checked || checkBox3.Checked || checkBox4.Checked || checkBox5.Checked ? g.Sum(s => s.amount) : null,                           
                   }).Distinct();         
        registrDataGridView.DataSource = regi.ToList();
    }

В комментарии показано,чего примерно я хочу добиться. В данном случае группирует только по g.company, мне же нужно сделать такую группировку по всем полям. Результат показан на скришоте.

Для company - правильно выводит. Для даты ,как и ожидалось - не правильно.Должно выводить дату. Так и для любых других полей - только их значения. Если группировку не производить совсем,то неправильно считает значения quantity и amount(они должны выводиться всегда).

При группировке в виде group r by new { r.company,r.city,r.country,r.manager } into g ,происходит следующее:

Вот код:

`var  regi = (from r in db.Registrs.ToList() 
                       group r by new { r.company,r.city,r.country,r.manager } into g
                         //group r by r.city into f
                       select new
                      {
                          // Date = checkBox1.Checked ? (DateTime?) r.date  : (DateTime?)null,
                           // Company = checkBox2.Checked ? (from s in db.Registrs group s by s.company into g select g.Key) : null,
                           Company = checkBox2.Checked ? g.Key : null,
                           City = checkBox3.Checked ? g.Key : null,                                         
                            Country = checkBox4.Checked ? g.Key : null,
                            Manager = checkBox5.Checked ? g.Key : null,
                            Quantity = checkBox1.Checked || checkBox2.Checked || checkBox3.Checked || checkBox4.Checked || checkBox5.Checked ? g.Sum(s => s.quantity) : null,
                            Amount = checkBox1.Checked || checkBox2.Checked || checkBox3.Checked || checkBox4.Checked || checkBox5.Checked ? g.Sum(s => s.amount) : null,                           
                       }).Distinct();         
            registrDataGridView.DataSource = regi.ToList();`
Answer 1

Вам нужно в формирование ключа группировки добавить условие ваших чекбоксов. Т.е. примерно так:

group r by new { Date=checkBox1.Checked ? r.Date:null,
                 Company=checkBox2.Checked?r.Company:null 
                 ... 
               } into g

При выводе таблицы, соответственно, выводить r.Key.Date, r.Key.Company и т.д.

Answer 2

Используйте для группировки анонимный тип, запись вида:

group r by new { r.company, r.city } into g

Для ознакомления: Практическое руководство. Группировка результатов запросов (Руководство по программированию на C#)

READ ALSO
Добавление using в динамическую компиляцию

Добавление using в динамическую компиляцию

Всем доброго времениИзучая динамическую компиляцию наткнулся на проблему - при добавлении некоторых using в текст кода компилируемой программы,...

261
Как перерисовывать DataGridView после запроса LINQ

Как перерисовывать DataGridView после запроса LINQ

Есть DGV,в которую считывается таблица из бд(с помощью класса linq2sql)Визуально это выглядит вот так:

276
Проблема с кодировкой UTF-8 через WebSocket

Проблема с кодировкой UTF-8 через WebSocket

Создал ASPNET Core чат на WebSocket'ах

376
Не открывается новое окно

Не открывается новое окно

Если значения параметров нулевые - запускается окно настроек, где должен их ввести (сохранения настроек проихводится в SettingsViewModel)Проблема:...

225