Я предполагаю, что вы на самом деле используете Entity Framework Core, хотя ваш вопрос помечен просто как entity-framework. Причина в том, что то, что у вас есть, будет естественным образом работать с Entity Framework, тогда как с Entity Framework Core оно определенно не будет работать вообще.
Основное различие между ними заключается в том, что EF Core не поддерживает отложенную загрузку. Благодаря свойствам виртуальной навигации EF динамически создается прокси-класс, производный от вашего класса сущностей. Затем свойства навигации динамически переопределяются, чтобы добавить к геттерам логику отложенной загрузки EF. Это приводит к тому, что доступ получателя свойств вызывает указанную логику ленивой загрузки и выдает запрос к базе данных для материализации связанного объекта или объектов.
Поскольку EF Core не поддерживает отложенную загрузку, ничего из этого не происходит. В результате, если вы не загрузите отношение явно или нетерпеливо, оно останется нулевым. Тем не менее, отложенная загрузка — плохая идея. Это может привести к огромной неэффективности, такой как проблема с запросом 1+N, когда, например, вы выполняете итерацию по списку и в конечном итоге выполняете запрос для каждого элемента в списке, чтобы материализовать некоторую связь в этом элементе. Если у вас много элементов, вы можете в конечном итоге выдать массу запросов, особенно если в дереве есть другие отношения. Скажем, например, что у вас есть список элементов со связанным объектом, а затем у самого связанного объекта есть связанный объект, к которому вам нужно получить доступ. Теперь вы каждый раз выдаете еще больше запросов на получение этого связанного объекта. Он может очень быстро выйти из-под контроля.
Длинные и короткие, гораздо лучше жадно загружать нужные вам отношения. Это фактически приведет к тому, что JOIN будут выданы в начальном запросе для получения всех отношений одновременно, только в этом одном запросе. Если не считать этого, явная загрузка по-прежнему предпочтительнее, поскольку, по крайней мере, вы тогда будете знать о конкретных запросах, которые вы выдаете, и можете четко видеть, если что-то начинает выходить из-под контроля.
UserManager
, тем не менее, не дает вам возможности выполнять интенсивные нагрузки. В результате, если вы используете его для получения пользователя, единственным вариантом является явная загрузка связанной сущности. Однако это не обязательно плохо, так как это всего лишь один дополнительный запрос.
var currentUser = await _userManager.GetUserAsync(User);
await _dbContext.Entry(currentUser).Reference(u => u.UserImage).LoadAsync();
Теперь вы можете получить доступ к связанному изображению.
В качестве альтернативы вы можете вместо этого запросить пользователя из контекста, а затем одновременно загрузить изображение:
var currentUser = await _dbContext.Users.Include(u => u.UserImage).SingleOrDefault(u => u.Id == User.Identity.GetUserId());
Это выдаст только один запрос с соединением отношения изображения.
person
Chris Pratt
schedule
29.01.2018