[英]ASP.NET MVC 5 Entity Framework - Relations
我目前正在开发一个Web应用程序。 我正在使用Identity进行身份验证和用户角色。
我希望我的应用程序中的每个用户都有一个关联的“机构”。 该机构包含名称和描述。 这是我的IdentityUser类:
public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
[Display(Name="Institution")]
public Institution Institution { get; set; }
}
当我更新我的数据库时,执行Seed方法,这个,我正在创建一个具有“admin”角色的用户,并且我关联了一个机构。 这是我的种子方法:
if (!context.Users.Any(u => u.UserName == "mxfragz"))
{
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new IdentitiesDb()));
roleManager.Create(new IdentityRole("admin"));
var store = new UserStore<ApplicationUser>(context);
var manager = new UserManager<ApplicationUser>(store);
var user = new ApplicationUser { UserName = "mxfragz" };
user.Institution = new Institution() { Name = "London", Description="Description" };
manager.Create(user, "password");
manager.AddToRole(user.Id, "admin");
}
我的问题是,当我在我的Web应用程序中创建一个新用户时,我找不到关联现有机构的方法(这里只创建了“伦敦”)。 根据我到目前为止所做的工作,当我创建用户时,我获取所选机构的ID并找到现有机构,以便将其与我的用户中定义的Institution属性相关联。 当我这样做时,实体框架不是关联已找到的现有机构,而是创建一个新机构,并将其关联到我的用户。 我最终得到了两个具有相同名称和描述的不同机构。 这是我的代码:
public async Task<ActionResult> Create(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser() { UserName = model.Username, Email = string.Empty };
int selected = int.Parse(model.SelectedInstitution);
user.Institution = new InstitutionsDb().Institutions.Where(x => x.Id == selected).First();
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new IdentitiesDb()));
UserManager.AddToRole(user.Id.ToString(), roleManager.Roles.Where(x => x.Id == model.SelectedRole.ToString()).First().Name);
return RedirectToAction("Index", "Users");
}
else
{
AddErrors(result);
}
}
model.Roles = GetRoles();
model.Institutions = GetInstitutions();
return View(model);
}
我发现了几个关于使用Attach方法的主题,但即使我尝试使用它,它也无效。 难道我做错了什么 ? 或者有什么方法可以做我想做的事情?
外键关系需要通过Institution上的虚拟集合以及ApplicationUser上的实际外键值进行公开。
public class ApplicationUser : IdentityUser
{
//...
public int InstitutionId { get; set; }
[Display(Name="Institution")]
[ForeignKey("InstitutionId")] //This attribute isn't strictly necessary but adds clarity
public Institution Institution { get; set; }
}
public class Institution
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<User> Users { get; set; }
}
EF将根据下面显示的InstitutionId自动在虚拟财产上附加相关的机构。
我建议刚加入DbSet<Institutions>
的ApplicationDbContext
,而不是它自己的InstitutionsDb
背景下,这可能是你的问题的一部分,因为UserManager
势必只对ApplicationDbContext
或曾经方面已配置诠释他IdentityConfig.cs
文件。
public async Task<ActionResult> Create(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser() { UserName = model.Username, Email = string.Empty };
int selected = int.Parse(model.SelectedInstitution);
var context = HttpContext.GetOwinContext().Get<ApplicationDbContext>()
//Set the id
user.InstitutionId = context.Institutions.Where(x => x.Id == selected).First().Id;
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new IdentitiesDb()));
UserManager.AddToRole(user.Id.ToString(), roleManager.Roles.Where(x => x.Id == model.SelectedRole.ToString()).First().Name);
return RedirectToAction("Index", "Users");
}
else
{
AddErrors(result);
}
}
model.Roles = GetRoles();
model.Institutions = GetInstitutions();
return View(model);
}
这应该允许您从UserManager
检索ApplicationUser
时调用user.Institution.Name
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.