Как включить другое поле в группу С помощью

#c# #linq #group-by

#c# #linq #группировать по

Вопрос:

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

Итак, дерево должно выглядеть следующим образом

 |
| - fleetName  -- fleet_id as node key
|  |
|  |--- plate_number  -- gps_device_id as node key
| - plate_number   -- for cars wont belong to any fleet      
  

customer_cars

 CREATE TABLE tracker.customer_cars
(
  customer_car_id integer NOT NULL DEFAULT nextval('customer_cars_car_id_seq'::regclass),
  gps_device_id integer,
  plate_number  string
  user_id text NOT NULL,
  fleet_id integer,

  CONSTRAINT customer_cars_idx PRIMARY KEY (customer_car_id),
  CONSTRAINT cars_gps_device_fk FOREIGN KEY (gps_device_id)
      REFERENCES tracker.gps_devices (gps_device_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fleet_fk FOREIGN KEY (fleet_id)
      REFERENCES tracker.fleet_cars (fleet_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
  

fleet_cars

 CREATE TABLE tracker.fleet_cars
(
  fleet_id serial NOT NULL,
  fleet_name text,
  user_id text NOT NULL,
  CONSTRAINT fleet_idx PRIMARY KEY (fleet_id)
)
  

Что я пытаюсь

     var customer_cars = db.customer_cars
              .Include(c => c.gps_devices)
              .Include(c => c.fleet_cars)
              .Where(c => c.user_id.CompareTo(UserId) == 0)  
              .GroupBy(c => c.fleet_id,
                       c => c.fleet_cars,
                       (key, g) => new
                       {
                           FleetID = key,                                   
                           Cars = g.ToList()
                       }
              );
  

Но его нет fleet_name , только fleet_id , а в машинах есть customer_cars строки без gps_device_id

 foreach (var fleet in customer_cars)
{
    -- have id but no name
    string fleet_id = fleet.FleetID.HasValue ? fleet.FleetID.ToString() : "0"; 

    foreach (var car in fleet.Cars ){
        string fleet_name = car.fleet_name; -- have fleet_name
        string gps_id = car.gps_device_id ; -- dont have gps_device_id             
    }
}
  

Комментарии:

1. Попробуйте : .GroupBy(c => new {c.fleet_id, c.fleet_cars}). Чтобы получить name, вам нужно объединить две таблицы по идентификатору.

2. @jdweng в этом случае fleet in customers_cars является коллекцией, а не объектом fleet. Я должен был fleet = {fleet_id, fleet_name, list<cars>}

3. Я сказал, что вам нужно использовать объединение. Смотрите msdn : code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

4. @jdweng Проблема заключалась в том, что я удалил SELECT часть, когда изменение на ваше GROUP BY сейчас работает нормально. Спасибо

Ответ №1:

Немного изменив свою группу по ключу, вы получите то, что хотите:

 var customer_cars = db.customer_cars
                      .Include(c => c.gps_devices)
                      .Include(c => c.fleet_cars)
                      .Where(c => c.user_id.CompareTo(UserId) == 0)  
                      .GroupBy(c => new { c.fleet_id, c.fleet_cars})
                      .Select(gr => new
                      {
                          FleetID = gr.Key.fleet_id,     
                          FleetName = gr.Key.fleet_cars.fleet_name,                                  
                          Cars = gr.ToList()
                      });
  

Комментарии:

1. Это намного лучше. Теперь просто нужно название флота.

2. @JuanCarlosOropeza Привет, ты отредактировал мой ответ. Вы имеете в виду, что это то, что вы хотите, и это сработало или не сработало?

3. Да, я только что протестировал это и обнаружил сам. Теперь проверяем, получен ли правильный результат.

4. @JuanCarlosOropeza Allrgiht

5. @JuanCarlosOropeza Конечно. По сути, в вашей реализации содержимое групп, которые были созданы на основе c.fleet_id, содержало соответствующие fleet_cars для каждого fleet_id. В то время как в этой версии группировка основана как на fleet_id, так и на fleet_cars. Для подробного объяснения GroupBy, если у вас есть время, прочитайте это codeblog.jonskeet.uk/2011/01/01 /… принесло бы дивиденды.