我在VS 2012 RC上使用EF 5 rc,出现了一些问题。可以肯定,这与我在数据库和EF中的知识有关,而不是与我使用的软件的版本号有关:)
因此,我有3个班级。用户,角色和权利。
用户类别
public class User
{
[Key]
public int UserId { get; private set; }
[Required]
public string EmailAddress { get; internal set; }
[Required]
public string Username { get; internal set; }
public ICollection<Role> Roles { get; set; }
// More properties
}
正确的阶级
public class Right
{
public virtual int RightId { get; set; }
public virtual string Description { get; set; }
}
角色类别
public class Role
{
public virtual int RoleId { get; set; }
public virtual string Description { get; set; }
public virtual ICollection<Right> Rights { get; set; }
}
语境
class MyContext : DbContext
{
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<Role> Roles { get; set; }
public virtual DbSet<Right> Rights { get; set; }
}
现在,我想为用户添加角色,并为角色添加权限。但是我也想确保有可能添加相同的权限,可以将其添加到不同的角色。
var role1 = new Role()
{
Description = "role1"
};
var role2 = new Role()
{
Description = "role2"
};
var right = new Right()
{
Description = "right"
};
context.Rights.Add(right);
context.Roles.Add(role1);
context.Roles.Add(role2);
role1.Rights = new List<Right>();
role2.Rights = new List<Right>();
role1.Rights.Add(right);
role2.Rights.Add(right);
/**** ERROR ****/
context.SaveChanges();
我越来越
InvalidOperationException:违反多重性约束。关系“ Role_Rights”的角色“ Role_Rights_Source”的多重性为1或0..1。
我究竟做错了什么 ?
另外,我对创建新列表(例如,
role1.Rights = new List<Right>();
role2.Rights = new List<Right>();
推荐的方法是什么? Rights属性为null。因此,如果不进行更新,我将无法添加任何内容。
最佳答案
问题是EF用于推断关系的约定。它认为该关系是一对多的,但是您想要多对多的(角色可以具有多个权限,并且该权限可以用于多个角色)。
有两种解决方法:
选项1:在右侧创建导航属性:
public class Right
{
public virtual int RightId { get; set; }
public virtual string Description { get; set; }
public virtual ICollection<Role> Roles { get; set; }
}
现在,EF约定将检测关系两侧的集合,并正确使用多对多多重性而不是一对多
选项2:使用Fluent-API告诉EF您想要多对多关系:
public class MyContext : DbContext
{
public virtual DbSet<User> Users { get; set; }
public virtual DbSet<Role> Roles { get; set; }
public virtual DbSet<Right> Rights { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Role>()
.HasMany(r => r.Rights)
.WithMany();
}
}
现在,EF知道即使
Right
没有Right
的导航属性,也可以将Role
分配给多个角色。如果
Role
可以分配给多个用户,则还必须使用多对多关系