无法在 Core Identity 的 ApplicationUser 中保留关系
Cannot persist relations in Core Identity's ApplicationUser
我找不到正确扩展 ASP.NET Core 的 IdentityUser
的方法(扩展后:ApplicationUser
)。我可以覆盖它并从其他模型 link 它,但不能 link 从用户到其他模型。 CustomTag
等简单数据有效。
问题源代码:https://github.com/chanibal/CoreIdentityIssue
或者,具体来说,it's second commit that contains all the changes over the default template
我做了什么:
- 创建了新项目:
ASP.NET 核心 Web 应用程序(模型-视图-控制器)
身份验证:个人用户帐户,在应用程序中存储用户帐户
更新了数据库
更改了覆盖 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
}
并迁移更改
我正在以这种方式更新条值:
/// 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
模型:
使用 Visual Studio 16.3.9
EF 永远不会自动加载相关实体。您必须急切地或明确地加载关系。预先加载是首选方式,因为它通过连接在单个查询中获取所有数据。但是,UserManager<TUser>
无法提供预先加载关系的方法。因此,您有两个选择:
显式加载关系。不过,这将需要额外的查询。
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.
通过用户 ID 从上下文中查询用户,而不是使用 UserManager<TUser>
:
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var user = await _context.Users.Include(x => x.Bar).SingleOrDefaultAsync(x => x.Id == userId);
我找不到正确扩展 ASP.NET Core 的 IdentityUser
的方法(扩展后:ApplicationUser
)。我可以覆盖它并从其他模型 link 它,但不能 link 从用户到其他模型。 CustomTag
等简单数据有效。
问题源代码:https://github.com/chanibal/CoreIdentityIssue
或者,具体来说,it's second commit that contains all the changes over the default template
我做了什么:
- 创建了新项目:
ASP.NET 核心 Web 应用程序(模型-视图-控制器)
身份验证:个人用户帐户,在应用程序中存储用户帐户
更新了数据库 更改了覆盖
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 }
并迁移更改
我正在以这种方式更新条值:
/// 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
模型:
使用 Visual Studio 16.3.9
EF 永远不会自动加载相关实体。您必须急切地或明确地加载关系。预先加载是首选方式,因为它通过连接在单个查询中获取所有数据。但是,UserManager<TUser>
无法提供预先加载关系的方法。因此,您有两个选择:
显式加载关系。不过,这将需要额外的查询。
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.
通过用户 ID 从上下文中查询用户,而不是使用
UserManager<TUser>
:var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); var user = await _context.Users.Include(x => x.Bar).SingleOrDefaultAsync(x => x.Id == userId);