ASP.NET Core 2 Identity/Entity 框架 - 如何在用户 class 中获取自定义属性?

ASP.NET Core 2 Identity/Entity Framework - How to get the custom properties within the User class?

目前我通过以下方式获取用户:

ApplicationUser currentUser = await _userManager.GetUserAsync(User);

但我发现以这种方式它不包含自定义属性,例如:

public virtual UserImage UserImage { get; set; }

所以每次我需要得到这样的东西时 属性 我写了一个方法来使用实体框架从数据库中获取,比如:

public async Task<UserImage> GetUserImage(string userId) =>
        await _dBcontext.UserImage.SingleOrDefaultAsync(u => u.ApplicationUserId == userId);

我想通过仅调用

await _userManager.GetUserAsync(User);
在应用程序中(在服务器上,而不是 cookie)缓存所有用户属性 有这样的方法吗?

看看这个帖子:asp.net forum

Rules for lazy loading:

context.Configuration.ProxyCreationEnabled should be true. context.Configuration.LazyLoadingEnabled should be true. Navigation property should be defined as public, virtual. Context will NOT do lazy loading if the property is not defined as virtual.

希望对您有所帮助 ;)

我假设您 实际上 使用 Entity Framework Core,即使您的问题只用实体框架标记。原因是你拥有的东西自然会与 Entity Framework 一起工作,而它绝对不会与 Entity Framework Core 一起工作。

两者之间的主要区别在于 EF Core 支持延迟加载。使用 EF 虚拟导航属性,动态创建代理 class,派生自您的实体 class。然后动态覆盖导航属性以将 EF 的延迟加载逻辑添加到 getter。这会导致访问 属性 getter 以调用所述延迟加载逻辑并向数据库发出查询以具体化相关实体。

由于 EF Core 不支持延迟加载,因此 none 发生了这种情况。因此,除非您急切地或明确地加载关系,否则它会保持为空。然而,延迟加载从一开始就是一个坏主意。它会导致巨大的低效,例如 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());

这将只发出一个带有图像关系连接的查询。