Получить последнюю детскую запись - EF Core - PullRequest
0 голосов
/ 19 декабря 2018

Таблица Users имеет несколько связей с другой таблицей

Итак, вот код фрагмента

var users = DbContext.Users
           .Include(x => x.ApplicationUserGroups)
                .ThenInclude(x => x.ApplicationGroup)
           .Include(x => x.FormSubmit)
                .ThenInclude(x => x.FormLevel)
           .Where(x => true);

Итак, теперь мне нужна последняя запись из FormSubmit.Поэтому я изменил запрос примерно так:

var users = DbContext.Users
           .Include(x => x.ApplicationUserGroups)
                .ThenInclude(x => x.ApplicationGroup)
           .Include(x => x.FormSubmit.OrderByDescending(i => i.CreationDate).Take(1))
                .ThenInclude(x => x.FormLevel)
           .Where(x => true);

Но я получил исключение:

"Message": "The Include property lambda expression 'x => {from FormSubmit i in x.FormSubmit orderby [i].CreationDate desc select [i] => Take(1)}' is invalid. The expression should represent a property access: 't => t.MyProperty'. To target navigations declared on derived types, specify an explicitly typed lambda parameter of the target type, E.g. '(Derived d) => d.MyProperty'. For more information on including related data, see http://go.microsoft.com/fwlink/?LinkID=746393."

Любая идея, как получить последнюю запись из FormSubmit

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

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

Вы просто можете 'т Include() так использовать.Include() используется только для извлечения всех связанных записей.

Если вам нужна только одна связанная запись, вам нужно сделать это отдельно.Например:

var users = DbContext.Users
           .Include(x => x.ApplicationUserGroups)
                .ThenInclude(x => x.ApplicationGroup)
           .Where(x => true);

foreach (var user in users) {
    var latest = DbContext.FormSubmits.Include(s => s.FormLevel).Where(s => s.UserId == user.UserId).OrderByDescending(i => i.CreationDate).FirstOrDefault()
    //Do other stuff...
}

При таком способе только будет извлекаться последняя запись для каждого пользователя.Если вы выполните .Include(x => x.FormSubmit).ThenInclude(x => x.FormLevel) в своем первом запросе, а затем отфильтруете, он в конечном итоге получит все представлений для каждого пользователя, что является большим количеством данных, чем вы собираетесь использовать.

0 голосов
/ 19 декабря 2018

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

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

1) Если вы хотите последний FormSubmit определенного пользователя:

var users = DbContext.Users
           .Include(x => x.ApplicationUserGroups)
                .ThenInclude(x => x.ApplicationGroup)
           .Include(x => x.FormSubmit)
                .ThenInclude(x => x.FormLevel)
           .Where(x => true && x.UserId == userId).FirstOrDefault();

var latestFormSubmit = users.Select(u => u.FormSubmit).OrderByDescending(fs => fs.CreationDate).FirstOrDefault();

2) Если вы хотите последний FormSubmit среди всех пользователей:

var users = DbContext.Users
           .Include(x => x.ApplicationUserGroups)
                .ThenInclude(x => x.ApplicationGroup)
           .Include(x => x.FormSubmit)
                .ThenInclude(x => x.FormLevel)
           .Where(x => true).ToList();

var latestFormSubmit = users.SelectMany(u => u.FormSubmit).OrderByDescending(fs => fs.CreationDate).FirstOrDefault();

    //Or

var latestFormSubmit = DbContext.FormSubmits.Include(x => x.FormLevel).OrderByDescending(fs => fs.CreationDate).FirstOrDefault();

Примечание. Вы можете опустить .Include(x => x.ApplicationUserGroups).ThenInclude(x => x.ApplicationGroup) в запросе, если вам нужна только последняя FormSubmit.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...