C# ASP.NET Core 2身份/实体框架-如何在用户类中获取自定义属性?

C# ASP.NET Core 2身份/实体框架-如何在用户类中获取自定义属性?,c#,entity-framework,asp.net-core-2.0,asp.net-core-identity,C#,Entity Framework,Asp.net Core 2.0,Asp.net Core Identity,目前,我确实通过以下方式获得用户: ApplicationUser currentUser = await _userManager.GetUserAsync(User); 但我发现,通过这种方式,它不包含自定义属性,例如: public virtual UserImage UserImage { get; set; } 因此,每当我需要获取此类属性时,我都会编写一个方法,以使用实体框架从db获取,如: public async Task<UserImage> GetUserIm

目前,我确实通过以下方式获得用户:

ApplicationUser currentUser = await _userManager.GetUserAsync(User);
但我发现,通过这种方式,它不包含自定义属性,例如:

public virtual UserImage UserImage { get; set; }
因此,每当我需要获取此类属性时,我都会编写一个方法,以使用实体框架从db获取,如:

public async Task<UserImage> GetUserImage(string userId) =>
        await _dBcontext.UserImage.SingleOrDefaultAsync(u => u.ApplicationUserId == userId);
我希望在服务器上的应用程序中缓存,而不是通过调用cookie来缓存所有用户属性 await _userManager.GetUserAsync(User);
有这样一种方法吗?

看看这个线程:

延迟加载规则:

context.Configuration.ProxyCreationEnabled应为true。 context.Configuration.LazyLoadingEnabled应为true。航行 属性应定义为公共的、虚拟的。语境不行 如果属性未定义为虚拟,则延迟加载


我希望这会有所帮助

我将假设您实际使用的是实体框架核心,即使您的问题只标记了实体框架。原因是您所拥有的将自然地与实体框架一起工作,然而,它绝对不会与实体框架核心一起工作

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

由于EF Core不支持延迟加载,因此不会发生任何这种情况。因此,除非您急切地或显式地加载关系,否则它将保持null。然而,延迟加载首先是个坏主意。它可能会导致巨大的低效,例如1+N查询问题,例如,您迭代一个列表,最终对列表中的每个项发出一个查询,以具体化该项上的某些关系。如果您有很多项,那么最终可能会发出大量查询,特别是当树中进一步涉及其他关系时。例如,假设您有一个包含相关实体的项目列表,然后该相关实体本身有一个您需要访问的相关实体。现在,每次都会发出更多的查询来获取相关实体。它可以很快失去控制

不管是长是短,急切地加载你需要的关系要好得多。这实际上会导致在初始查询中发出的连接在同一时间获取所有关系,仅在一个查询中。除此之外,显式加载仍然优于显式加载,因为至少您知道您正在发出的特定查询,并且可以清楚地看到事情是否开始失控

然而,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());
这将只发出一个带有图像关系联接的查询