gpt4 book ai didi

.net - 将 ASP.Net Identity 表链接到用户详细信息表

转载 作者:行者123 更新时间:2023-12-04 01:53:17 25 4
gpt4 key购买 nike

我正在尝试将我的 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/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com