我在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可以分配给多个用户,则还必须使用多对多关系

09-17 13:15
查看更多