2

VS2012RCでEF5rcを使用していますが、いくつか問題があります。私が使用しているソフトウェアのバージョン番号よりも、データベースと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です。だから私はそれを更新せずにそれに何も追加することはできません。

4

2 に答える 2

1

問題は、EFが関係を推測するために使用する規則です。関係は1対多であると考えられますが、多対多が必要です(ロールには複数の権限を設定でき、権限は複数のロールで使用できます)。

これを解決するには、次の2つのオプションがあります。

オプション1:右側にナビゲーションプロパティを作成します。

public class Right
{
    public virtual int RightId { get; set; }
    public virtual string Description { get; set; }

    public virtual ICollection<Role> Roles { get; set; }
}

これで、EF規則は関係の両側でコレクションを検出し、1対多ではなく多対多の多重度を正しく使用します。

オプション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 に答える
1

Ladislavの回答はエラーに対してうまく機能するはずです。

使用に不快感を感じるというあなたの問題について:

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

これらのプロパティをコンストラクターで新しいリストに初期化する必要があります。そうすれば、Roleのすべてのインスタンスに対して実行されます。

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 に答える