Из вашего описанного поведения кажется, что отложенная загрузка либо отключена, либо недоступна (т. Е. EF Core <= 2.1) </p>
Ленивая загрузка назначит прокси для связанных ссылок, которые не были загружены, так что если эти к последующему доступу, запрос БД к DbContext будет сделан для их получения. Это позволяет получать данные «по мере необходимости», но может привести к значительному снижению производительности.
В качестве альтернативы вы можете загружать связанные данные. Например:
var pgSARS = context.StockAppreciationRights.Include(x => x.SarVestingUnits).ToList();
сообщит EF, чтобы загрузить права StockAppreciation и предварительно выбрать любые единицы передачи для каждой из этих записей. Вы можете использовать Include
и ThenInclude
для детализации и предварительной выборки любого количества зависимостей.
Причина, по которой ваш последний пример работает, заключается в том, что EF автоматически заполняет отношения, о которых знает контекст. Когда вы загружаете первый набор, он не разрешит ни одну из связанных сущностей, однако, загружая второй набор, EF уже знает о связанных других сущностях и автоматически установит эти ссылки для вас.
Реальная сила EF, однако, заключается не в том, чтобы иметь дело с такими объектами, как отображение 1: 1 в таблицы (вне редактирования / вставки), а в том, чтобы использовать проекцию для извлечения реляционных данных для заполнения того, что вам нужно. Использование Select
или методов ProjectTo
Automapper означает, что вы можете извлекать любые данные, которые вы хотите, через сопоставленные отношения EF, и EF может создать вам эффективный запрос для его извлечения, вместо того, чтобы беспокоиться о ленивой или энергичной загрузке. Например, если вы хотите получить список наделенных юнитами с соответствующими правовыми данными:
var sars = context.StockAppreciationRights.Select(x => new SARSummary
{
UbsId = x.UbsId,
Units = x.Units,
VestDate = x.VestDate,
GrantDate = x.Sar.GrantDate,
ExpirationDate = x.Sar.ExpirationDate,
UnitsGranted = x.Sar.UnitsGranted,
GrantPrice = x.Sar.GrantPrice
}).ToList();
Из оператора Select
вы можете получить доступ к любым связанным деталям, чтобы сгладить их в модель представления, которая служит ваши непосредственные потребности или даже составьте иерархию моделей представлений, упрощенную для того, что нужно представлению / потребителю.