我正在尝试将我的身份用户表链接到我创建的用于跟踪其他用户信息的用户详细信息表。该用户详细信息表称为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中执行此操作吗?
谢谢
答案 0 :(得分:2)
您的主要问题很简单,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身份与ASP.NET成员资格不同。对于后者,您必须有一个单独的UserProfile
,因为成员资格中的“用户”不可扩展。在Identity中,用户 是可扩展的,因此,如果要在其上添加其他个人资料信息,只需将其添加到类中即可:
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; } // FirstName
public string LastName { get; set; } // LastName
}
请注意,我也在这里修剪了很多碎屑。覆盖Id
并使其自动实现没有意义。另外,您显然不需要UserName
的{{1}}属性,因为UserProfile
已经拥有了,这当然意味着您的IdentityUser
也拥有它。