Как увеличить производительность при использовании группы в LINQ

#c# #performance #linq #model-view-controller

Вопрос:

База данных

 Cars       | CarDetails         | Owners
----------------------------------
Id         | CarDetailId        | Id
Name       | CarId              | CarId
Type       | CarId              | OwnerName
           |                    | PhoneNumber
 

Код LINQ

 var intiQuery = from c in Cars
              join cd in CarDetails
              join o in Owners
              select new { c,cd,o}

var results = from qry in intiQuery 
                           group new { qry.c, qry.cd, qry.o} by qry.c.Id into g
                           select new
              select new { CarId= g.Key,
                           Name = g.Select(g=>g.c.Name).FirstOrDefault(),
                           Type = g.Select(g=>g.c.Type).FirstOrDefault(),
                           Price= g.Select(g=>g.cd.Price).FirstOrDefault(),
                           OwnerName= g.Select(g=>g.o.OwnerName).FirstOrDefault(),
                           PhoneNumber= g.Select(g=>g.o.PhoneNumber).FirstOrDefault(),
                         }
 

Мой вопрос просто в том, как повысить производительность при вызове этого запроса, как вы можете видеть для каждого поля, мне это нужно.Выберите().FirstOrDefault (), чтобы получить соответствующие данные. Если скажем, что у меня есть 100 данных, мне нужно будет получить данные по одному 500 раз, для отображения данных потребуется целая вечность.

Дополнительная информация на случай, если кому-то не ясно.

 Cars
Id    |Name            |Type
-----------------------------------
1     |Toyota          |Family

CarDetails
CarDetailId | CarId       | Price
-----------------------------------
1           | 1           | 200000

Owners
Id| CarId       | OwnerName   | PhoneNumber
-----------------------------------
1 | 1           | Mitch       | 48774800
2 | 1           | Camilo      | 87404078
 

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

 CarId| Name   | Type   | Price  |OwnerName        |PhoneNumber 
----------------------------------------------------------------------
1    | Toyota | Family | 200000 | Mitch,Camilo    | 48774800,87404078
 

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

1. Почему вы используете перекрестные соединения вместо простых внутренних/левых соединений? Этот запрос не имеет смысла в том виде, в каком он написан в настоящее время. На самом деле, я даже не уверен, что это вообще компилируется

2. @MitchWheat@CamiloTerevinto, пожалуйста, еще раз прочтите мой вопрос, обновил Тай.

Ответ №1:

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

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

 var allCars = Cars.ToList();
var allCarDetails = CarDetails.ToList();
var allOwners= Owners.ToList();
 

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

 var results = (from car in allCars
               let owners = allOwners.Where(a => a.CarID == car.Id)

 select new
 {
     CarID = car.Id,
     car.Name,
     car.Type,
     Price = allCarDetails.Where(a => a.CarID == car.Id).Select(a => a.Price).SingleOrDefault(),

     OwnerName = String.Join(',', owners.Select(a => a.Name)),
     PhoneNumber = String.Join(',', owners.Select(a => a.PhoneNumber))
 }
 );
 

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