Итак, у вас есть последовательности Users
и Trackings
.Каждый User
имеет ноль или более Trackings
, каждый Tracking
принадлежит ровно одному User
с использованием внешнего ключа UserIdFk
.Прямые отношения «один ко многим».
User Tracking
Id | Name Id | UserIdFk | <other properties>
1 | Jan 10 | 1 | A
2 | Piert 11 | 1 | B
12 | 2 | C
var browserUser = db.Tracking.Include(t => t.Users).ToList();
Результат: последовательность из 3 отслеживаний, каждый со своим пользователем
Tracking: Id = 10, UserIdFk = 1; User: Id = 1; Name = Jan
Tracking: Id = 11, UserIdFk = 1; User: Id = 1; Name = Jan
Tracking: Id = 12, UserIdFk = 2; User: Id = 2, Name = Piert
Do GroupBy:
var browserUserFiltered = browserUser.GroupBy(x => x.userIdFk)
Результат: последовательность из 2 IGrouping
Group Key: 1; Elements:
Tracking: Id = 10, UserIdFk = 1; User: Id = 1; Name = Jan
Tracking: Id = 11, UserIdFk = 1; User: Id = 1; Name = Jan
Group Key: 2; Elements:
Tracking: Id = 12, UserIdFk = 2; User: Id = 2, Name = Piert
Продолжение после GroupBy:
.Select(g => g.First());
Результат: последовательность из двух элементов, по одному элементу в группе:
Tracking: Id = 10, UserIdFk = 1; User: Id = 1; Name = Jan
Tracking: Id = 12, UserIdFk = 2; User: Id = 2, Name = Piert
Вопрос: Как вы думаете, почему в вашем результате будет только один элемент?
В одном-многих вы можете пойти двумя путями:
- Получить пользователей с их отслеживаниями, что означает, что внутреннее групповое присоединение сделано.Каждый пользователь передается вашему процессу ровно один раз.Пользователи без данных отслеживания также в вашем результате.
- Получить отслеживания, каждый со своим пользователем.Внутренне внутреннее соединение сделано.Если у пользователя несколько отслеживаний, одни и те же пользовательские данные отправляются более одного раза.Пользователи без каких-либо данных отслеживания вообще не упоминаются.
Вам решать, что вы хотите.
Используйте Выбрать вместо Включить
Один изболее медленные части запросов к базе данных - это транспортировка выбранных данных в ваш процесс.Следовательно, разумно ограничить количество выбранных данных.
Если у пользователя 4 есть 1000 отслеживаний, то каждое отслеживание будет иметь внешний ключ UserId со значением, равным 4. Если вы используете «Включить» для выбора данных,одно и то же значение внешнего ключа будет отправлено 1000 раз, а вы уже знаете, что оно равно значению первичного ключа пользователя: 4. Какая трата!
При запросе данных всегда используйте Select и выберите толькосвойства, которые вы на самом деле планируете использовать.Используйте «Включить» только в том случае, если вы планируете обновить включенный элемент.
Поэтому, чтобы получить некоторых пользователей с (некоторыми из их) отслеживаниями, выполните следующий запрос:
var result = dbContext.Users
.Where(user => ...) // only if you don't want all Users
.Select(user => new
{
// Select only the User data you actually plan to use
Id = user.Id,
Name = user.Name,
...
Trackings = user.Trackings
.Where(tracking => tracking.Date >= startDate) // only if you don't want all Trackings
.Select(tracking => new
{
// again: select only the properties you plan to use
Id = tracking.Id,
Name = tracking.Name,
...
// not needed, you know the value: UserId = tracking.UserId
})
.ToList(),
});