我正在尝试在ApplicationUser上更新名为Municipality的属性。问题是,Municipality属性是一个已经存在于市政当局数据库表中的相关对象,所以我需要创建一个链接,而不仅仅是设置市政财产(在数据库中创建一个重复的市政当局)
我听说暴露外键可能是正确的方向(即明确地向ApplicationUser类添加一个MunicipalityId属性),如下所示:
public class ApplicationUser : IdentityUser
{
...
public int? MunicipalityId { get; set; }
[ForeignKey(nameof(MunicipalityId))]
public Municipality Municipality { get; set; }
}
...但是当使用以下代码设置MunicipalityId时,user.Municipality仍然为null
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> SelectRegion(SelectRegionViewModel selectRegionViewModel, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
var user = await _userManager.GetUserAsync(HttpContext.User);
if (user == null)
{
...
}
else
{
user.MunicipalityId = selectRegionViewModel.SelectedMunicipality;
using (var context = new ApplicationDbContext(
_serviceProvider.GetRequiredService<DbContextOptions<ApplicationDbContext>>()))
{
context.Entry(user).State = EntityState.Modified;
context.SaveChanges();
}
await _userManager.UpdateAsync(user);
}
return RedirectToAction(nameof(HomeController.Index), "Home");
}
如果我设置了外键,是否需要执行一些额外的步骤?查看dbo.AspNetUsers数据库表中的条目,看起来用户的Municipality已经设置正确,因为MunicipalityId已设置,但user.Municipality在上面的代码中始终为null(即使应用程序启动时也是如此) ApplicationUser具有有效的MunicipalityId)
答案 0 :(得分:0)
似乎我在正确的轨道上暴露了外键,只需要在ApplicationUser类上找到一种干净的方式来自定加载自定义属性Municipality。我这样做是通过创建一个自定义的UserStore类,其中包括Municipality:
public class ApplicationUserStore : UserStore<ApplicationUser>
{
public ApplicationUserStore(ApplicationDbContext context)
:base(context)
{
}
public override Task<ApplicationUser> FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken))
{
return Users
.Include(u => u.Municipality)
.Include(u => u.Roles)
.Include(u => u.Claims)
.Include(u => u.Logins)
.FirstOrDefaultAsync(u => u.Id == userId);
}
}
然后让框架通过在Startup ConfigureServices方法的这一部分中添加.AddUserStore来使用这个类:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 6;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders()
.AddUserStore<ApplicationUserStore>();
这实现了UserManager将返回填充了Municipality的用户,无需创建ApplicationDbContext并通过userManager查询我的查询
var user = await _userManager.GetUserAsync(HttpContext.User);