我能够成功创建一个用户。我现在正在尝试在创建过程中为用户分配一些角色。
我在Entity Framework中使用数据库优先方法。我尝试遵循一些教程并查看其他人的解决方案,但似乎无法使其正常工作。
我有3个表:User
,Role
和UserRole
(包含UserId
和RoleId
)。
User
和Role
之间的关系是多对多的。
Entity Diagram Showing Relationships
The Create view, which contains checkboxes
数据库上下文类:
public partial class MyDBEntities : DbContext
{
public MyDBEntities() : base("name=MyDBEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<Role> Roles { get; set; }
}
User.cs:
public partial class User
{
public User()
{
this.Roles = new HashSet<Role>();
}
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string Password_hash { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
Role.cs:
public partial class Role
{
public Role()
{
this.Users = new HashSet<User>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<User> Users { get; set; }
}
[HttpGet] Create():
public ActionResult Create()
{
return View(new UserCreateVM
{
Roles = db.Roles.Select(x => new RoleCheckboxVM
{
Id = x.Id,
Name = x.Name,
IsChecked = false
}).ToList()
});
}
[HttpPost] Create():
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(UserCreateVM vm)
{
User user = new User();
var selectedRoles = new List<Role>();
foreach (var r in db.Roles) // we query all the roles in the database
{
var checkbox = vm.Roles.Single(x => x.Id == r.Id);
checkbox.Name = r.Name; //updates the name on all our checkboxes
if (checkbox.IsChecked) //if checkbox is checked
{
selectedRoles.Add(r); //then we add the role to our selectedRoles
}
}
IList<Role> rolesList = user.Roles.ToList();
foreach (var toAdd in selectedRoles.Where(x => !rolesList.Contains(x))) //if roles is not already added
{
rolesList.Add(toAdd); //then we add them to the user roles
}
if (ModelState.IsValid)
{
//We update the data on the object
user.Username = vm.Username;
user.Email = vm.Email;
user.SetPassword(vm.Password_hash); //we hash the password
db.Users.Add(user);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(vm);
}
答案 0 :(得分:0)
我看不到您是何时将角色分配给user.roles的,正如我所看到的,您是将user.roles分配给RolesList而不是将roleList分配给user.roles。 这就是我要做的。
User user = new User()
{
Roles = db.Roles.Where(r => vm.Roles.Any(x => x.IsChecked && r.Id = x.Id)).ToList(),
Username = vm.Username,
Email = vm.Email
};
user.SetPassword(vm.Password_hash); //we hash the password
db.Users.Add(user);
db.SaveChanges();
答案 1 :(得分:0)
我终于想出了解决方法。
“多对多”表UserRole没有任何主键。因此,我添加了与UserId和RoleId一致的PK。
我删除了RolesList,因为我不需要它
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(UserCreateVM vm)
{
User user = new User();
var selectedRoles = new List<Role>();
foreach (var r in db.Roles) // we query all the roles in the database
{
var checkbox = vm.Roles.Single(x => x.Id == r.Id);
checkbox.Name = r.Name; //updates the name on all our checkboxes
if (checkbox.IsChecked) //if checkbox is checked
{
selectedRoles.Add(r); //then we add the role to our selectedRoles
}
}
foreach (var r in selectedRoles.Where(x => !user.Roles.Contains(x))) //if roles is not already added
{
user.Roles.Add(r); //then we add them to the user roles
}
if (ModelState.IsValid)
{
//We update the data on the object
user.Username = vm.Username;
user.Email = vm.Email;
user.SetPassword(vm.Password_hash); //we hash the password
db.Users.Add(user);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(vm);
}
然后在更新数据库表和数据库模型(edmx)之后,一切正常。