Выберите несколько столбцов из базы данных - PullRequest
0 голосов
/ 19 февраля 2019

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

var browserUser = db.Tracking.Include(t => t.Users).ToList();
var browserUserFiltered = browserUser.GroupBy(x => x.userIdFk).Select(g => g.First());


Снимок экрана фактического вывода
Модель базы данных

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

Итак, у вас есть последовательности 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(),
    });
0 голосов
/ 19 февраля 2019

Установите morelinq из npm, затем используйте users.DistinctBy(u=>userId).ToList()

https://www.nuget.org/packages/morelinq/

0 голосов
/ 19 февраля 2019

Попробуйте выбрать браузер и версию браузера по FirstOrDefault:

var browserUserFiltered = browserUser.GroupBy(x => x.userIdFk).Select(g => new { 
username= g.FirstOrDefault().username,
browser= g.FirstOrDefault().browser,
browserVersion= g.FirstOrDefault().browserVersion,
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...