无法在Core Identity的ApplicationUser中保持关系

问题描述 投票:4回答:1

我找不到正确扩展ASP.NET Core的IdentityUser的方法(扩展后为ApplicationUser)。我可以覆盖它并从其他模型链接它,但是不能从用户链接到其他模型。像CustomTag这样的简单数据也可以。

问题的源代码:https://github.com/chanibal/CoreIdentityIssue或者,具体来说,it's second commit that contains all the changes over the default template

我做了什么:

  1. 创建了新项目:ASP.NET Core Web应用程序(模型-视图-控制器)身份验证:单个用户帐户,在应用内存储用户帐户更新数据库
  2. 更改了覆盖IdentityUser的模型(如official docs:]

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
            {}
    
        public DbSet<Bar> Bars { get; set; }
        public DbSet<Foo> Foos { get; set; }
        public DbSet<ApplicationUser> ApplicationUsers { get; set; } //< doesn't help
    }
    
    public class ApplicationUser : IdentityUser
    {
        public string CustomTag { get; set; }   //< this works
        public Bar Bar { get; set; }            //< THIS DOES NOT WORK
    }
    
    public class Bar
    {
        public int Id { get; set; }
        public int Value { get; set; }
    }
    
    public class Foo
    {
        public int Id { get; set; }
        public ApplicationUser User { get; set; }   //< this works
    }
    

    ER diagram

    并迁移了更改

  3. 我通过这种方式更新Bar值:

    /// This should ensure a Bar is connected to a ApplicationUser
    /// and increment it's value
    [Authorize]
    public async Task<IActionResult> IncrementBar()
    {
        // This DOES NOT work
        var user = await _userManager.GetUserAsync(HttpContext.User);
        if (user.Bar == null)   //< this is always null
        {
            user.Bar = new Bar() { Value = 0 };
            // _context.Add(user.Bar); //< doesn't help
        }
        user.Bar.Value++;
        // await _userManager.UpdateAsync(user); //<> doesn't help
        // await _signInManager.RefreshSignInAsync(user);  //< doesn't help, starting to get desperate
        await _context.SaveChangesAsync();

        return RedirectToAction(nameof(Index));
    }

信息在数据库中,可通过SQL访问。但是不知何故,它并不能补充ApplicationUser模型:

SQL dump

使用Visual Studio 16.3.9

c# asp.net-core asp.net-core-mvc entity-framework-core asp.net-core-identity
1个回答
2
投票

EF不会自动加载相关实体。您必须热切或显式加载关系。较早的加载是首选方式,因为它确实合并在一起以在单个查询中获取所有数据。但是,UserManager<TUser>无法提供负载关系的方法。因此,您有两个选择:

  1. 明确加载关系。不过,这将需要一个额外的查询。

    var user = await _userManager.GetUserAsync(HttpContext.User);
    await _context.Entry(user).Reference(x => x.Bar).LoadAsync();
    // note: for collection props, you'd use `Collection(x => x.CollectionProp).LoadAsync()` instead.
    
  2. 从上下文中通过用户ID查询用户,而不使用UserManager<TUser>

    var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
    var user = await _context.Users.Include(x => x.Bar).SingleOrDefaultAsync(x => x.Id == userId); 
    
© www.soinside.com 2019 - 2024. All rights reserved.