我正在尝试将我的 Identity 用户表链接到我创建的用于跟踪其他用户信息的用户详细信息表。该用户详细信息表称为 UserProfile。
我遇到了这个链接,但它在 .NET Core 2.1 中不起作用:
Link ASP.NET Identity users to user detail table
这是我目前所拥有的:
public class ApplicationUser : IdentityUser
{
[Key]
public override string Id { get; set; }
[ForeignKey("Id")]
public virtual UserProfile UserProfile { get; set; }
}
[Table("UserProfile")]
public class UserProfile
{
[Key, ForeignKey("User")]
public string UserId { get; set; } // UserId (Primary key)
public string UserName { get; set; } // UserName
public string FirstName { get; set; } // FirstName
public string LastName { get; set; } // LastName
//[ForeignKey("Id")]
public virtual ApplicationUser User { get; set; }
}
但是,在我调用的代码中的其他地方:
var user = await _userMgr.FindByNameAsync(model.UserName);
并且 user.UserProfile 为空。
我尝试了很多数据注释的组合,甚至连流畅的api都无济于事。
modelBuilder.Entity<ApplicationUser>()
.HasOne(c => c.UserProfile)
.WithOne(t => t.User)
.HasForeignKey<UserProfile>(b => b.UserId);
我也尝试打开延迟加载,但这甚至无法加载该属性。
有谁知道如何在 .Net Core 2.1 中做到这一点?
谢谢
最佳答案
您的主要问题只是 UserManager
没有包含相关实体的功能,例如您的 UserProfile
.因此,您有两个选择:
UserProfile
随着ApplicationUser
例如,只需对数据库进行一次查询:var user = await _context.Users.Include(x => x.UserProfile).SingleOrDefaultAsync(x => x.UserName == model.UserName);
UserProfile
反而。但是,这将导致额外的查询,总共有两个:一个获取用户,一个获取相关配置文件:await _context.Entry(user).Reference(x => x.UserProfile).LoadAsync();
然而,坦率地说,你不应该有
UserProfile
根本。 ASP.NET Identity 与 ASP.NET Membership 不同。对于后者,您必须有一个单独的 UserProfile
因为 Membership 中的“用户”是不可扩展的。在 Identity 中,用户是可扩展的,因此如果您想要关于它的其他配置文件信息,只需将其添加到类中:public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; } // FirstName
public string LastName { get; set; } // LastName
}
请注意,我也在这里修剪了很多杂物。覆盖
Id
毫无意义然后让它自动实现。此外,您显然不需要 UserName
属性(property)来自 UserProfile
因为 IdentityUser
已经有了,这当然意味着您的 ApplicationUser
也有。更新
用户数据的持久化方式不一定会影响它是否可以声明。换句话说,您不必将数据逐字保存为声明,以便将其作为声明访问。仅源自
UserClaimsPrincipalFactory<TUser>
, 覆盖 CreateAsync
,然后将其注册到服务集合作为范围。public class MyClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser>
{
public MyClaimsPrincipalFactory(UserManager<TUser> userManager, IOptions<IdentityOptions> optionsAccessor)
: base(userManager, optionsAccessor)
{
}
public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
{
var principal = await base.CreateAsync(user);
((ClaimsIdentity)principal.Identity).AddClaims(new[]
{
new Claim(ClaimTypes.GivenName, user.FirstName),
new Claim(ClaimTypes.Surname, user.LastName),
// etc.
});
return principal;
}
}
然后在
ConfigureServices
:services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, MyClaimsPrincipalFactory>();
关于.net - 将 ASP.Net Identity 表链接到用户详细信息表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51996859/