2

我在 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; }
 }

现在,我想给一个用户添加角色,给一个角色添加权限。但我也想确保可以添加相同的Right可以添加到不同的角色

 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>();

推荐的方法是什么?权利属性为空。所以我不能在没有更新的情况下添加任何东西。

4

2 回答 2

1

拉迪斯拉夫的答案应该适用于该错误。

关于您对使用感到不舒服的问题:

role1.Rights = new List<Right>();

您应该在构造函数中将这些属性初始化为新列表,然后将为所有角色实例完成:

public class Role
{
    public virtual int RoleId { get; set; }
    public virtual string Description { get; set; }

    public virtual ICollection<Right> Rights { get; set; }

public Role ()
{
this.Rights =  new List<Right>();    
}
}
于 2012-07-23T11:09:56.277 回答
1

问题是 EF 用来推断关系的约定。它认为关系是一对多,但你想要多对多(角色可以有多个权限,并且权限可以在多个角色中使用)。

有两种选择可以解决这个问题:

选项 1:在 Right 中创建导航属性:

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也可以将 分配给多个角色。RightRole

如果Role可以将其分配给多个用户,则还必须使用多对多关系

于 2012-07-23T11:04:52.020 回答