В объявлении переменной donors
компилятор может определить тип donors
как List<Donor>
В назначении в желаемом коде доноры должны быть List<IGrouping<string, Donor>>
donors
не может быть одновременно обоих типов.
Предположим, у вас есть этот запрос:
List<IGrouping<string, Donor>> donors = _db.ONLINEDR_DONORS
.Where(d => d.DONOR_LIST_ID == id)
.GroupBy(d => d.SORT_NAME)
.ToList();
Этот запрос является локальным и дает вам ключи:
donors.Select(g => g.Key)
Этот запрос в смешанном режиме. Запрос отправляется в базу данных для каждого элемента в списке, чтобы получить его счет. Это потенциальная проблема производительности.
donors.Select(g => g.Count())
Такое поведение обусловлено различием между linqToObjects groupby и sql groupby.
- В sql groupby вы получаете ключ и агрегаты - без элементов.
- В LinqToObjects вы получаете ключ и элементы группы - и можете вычислять агрегаты из элементов.
Предположим, у вас есть этот запрос:
List<IGrouping<string, Donor>> donors = _db.ONLINEDR_DONORS
.Where(d => d.DONOR_LIST_ID == id)
.ToList()
.GroupBy(d => d.SORT_NAME)
.ToList();
В приведенном выше запросе записи сначала гидратируются, а затем группируются локально. Все запросы по результату локальные.
Этот запрос формирует данные результата от IGrouping<string, Donor>
до GroupShape
. GroupShape
- это класс, который вы создаете, который имеет свойства SortName и Count.
donors.Select(g => new GroupShape()
{
SortName = g.Key,
Count = g.Count()
});
Предположим, у вас есть этот запрос:
List<GroupShape> donors = _db.ONLINEDR_DONORS
.Where(d => d.DONOR_LIST_ID == id)
.GroupBy(d => d.SORT_NAME)
.Select(g => new {SortName = g.Key, Count = g.Count()})
.ToList()
.Select(x => new GroupShape()
{
SortName = x.SortName,
Count = x.Count
}).ToList();
Здесь группировка и подсчет выполняются в базе данных. Каждая строка сначала гидратируется в анонимный экземпляр, а затем копируется в экземпляр GroupShape
(класс, который вы создаете).