Вы правы, вам следует выбирать только те свойства, которые вы фактически планируете использовать, таким образом, передавая как можно меньше данных в локальный процесс.
LINQ знает два вида операторов: те, которые составляют запрос, и те, которые будут выполнять запрос. Композиторы - это методы LINQ, которые возвращают IQueryable<...>
(или IEnumerable<...>
), исполнители - это функции, которые не возвращают IQueryable
, а TResult
. Примеры: ToList
, FirstOrDefault
, Any
, Max
, ...
Вы должны всегда следить за тем, чтобы исполнитель был последним в вашем утверждении, если только вы не абсолютно уверены, что утверждения, следующие за исполнителем, не будут ограничивать объем данных.
db.Users.Select(user => new UserVm
{
...
FirstEnrolMentName = user.Enrolments
.OrderBy(enrolment => enrolment.StartDate)
.FirstOrDefault()
.EnrolmentName,
});
Интересно, будет ли это работать, если у вас есть пользователь без Enrolments
. Мое первое предположение было бы, что FirstOrDefault
вернет ноль, и, таким образом, у вас будет ArgumentNullException
, когда вы хотите получить EnrolmentName
Другая проблема заключается в том, что вы сначала выбираете одно полное Enrolment
, после чего отбрасываете все свойства регистрации, кроме имени. Было бы лучше выбрать только те свойства, которые вы планируете использовать, а затем использовать FirstOrDefault
:
var result = db.Users.Select(user => new UserVm
{
...
FirstEnrolMentName = user.Enrolments
.OrderBy(enrolment => enrolment.StartDate)
.Select(enrolment => enrolment.EnrolmentName)
.FirstOrDefault(),
});