web-dev-qa-db-ja.com

PersonとRoleの関係を定義するために、OnModelCreating(DbModelBuilder modelBuilder)関数に何を追加する必要がありますか?

WinFormsプロジェクトの.net 4.5でEntityFrameworkバージョン5.0を使用しています。

重要なエンティティを2つ作成しました

_    public class Role
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        public string Name { get; set; }
        public bool StockPermission { get; set; }
        public bool ItemPermission { get; set; }
        public bool OrderPermission { get; set; }
        public bool PersonPermission { get; set; }
        public bool StatisticPermission { get; set; }
    }

    public class Person
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        public String Name { get; set; }
        public String Nickname { get; set; }
        public String Contact { get; set; }
        public System.DateTime Created { get; set; }
        public String Pincode { get; set; }

        public virtual ICollection<Role> Role { get; set; }
        public virtual Person Creator { get; set; }
    }
_

およびdbContextクラス:

_    public class SusibarDbContext : DbContext
    {
        public DbSet<Entity.Role> Roles { get; set; }
        public DbSet<Entity.Person> Persons { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //base.OnModelCreating(modelBuilder);
        }
    }
_

personとRoleの関係を定義するためにOnModelCreating(DbModelBuilder modelBuilder)関数に追加する必要があるものを手伝ってくれませんか?

個人は多くの役割を持つことができますが(nullにすることはできません)、異なる個人が同じ役割を持つことができます。

人は1人の「作成者」人(nullの場合もあります)を持つことができ、異なる人は同じ「作成者」を持つことができます

あなたがとても親切である可能性がある場合は、解決策をアドバイスしてください:-(

14
eCorke

Fluent APIを使用する場合は、MSDNの このトピック をご覧ください。多対多の関係を使用する必要があります。EFは、Personが多くのロールを持つことができ、Roleが多くの人を持つ場合に必要なテーブルを作成します。このようなもの:

modelBuilder.Entity<Person>().HasMany(x => x.Roles).WithMany();

また、Fluent APIを使用せずにこの関係を作成できます。ナビゲーションプロパティICollection<Person> PersonsをRoleクラスに作成する必要があります。EFは適切なテーブルとリレーションシップも作成します。

16
klappvisor

このような何かが仕事をする必要があります:

PersonRoleというPOCOを作成します。これは、PersonRoleの間の関係をモデル化することを目的としています。

public class PersonRole
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public Person Person { get; set; }
    public Role Role { get; set; }
}

Personクラスで、以下を置き換えます。

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

で:

public virtual ICollection<PersonRole> PersonRoles { get; set; }

必要に応じて、以下をRoleクラスに追加できます。

public virtual ICollection<PersonRole> PersonRoles { get; set; }

これはオプションですが、特定のPeopleですべてのRoleを確認したい場合に役立ちます。

OnModelCreatingメソッドでは、このコードを使用して、PersonRoleがnull不可のPersonおよびRoleプロパティを強制することを確認します。

modelBuilder.Entity<PersonRole>().HasRequired(p => p.Person);
modelBuilder.Entity<PersonRole>().HasRequired(p => p.Role);

編集:

PersonRole POCOを作成する理由は、Roleを異なるユーザー間で再利用できるようにするためです。既存のpublic virtual ICollection<Role> Role { get; set; }を使用しても機能しますが、おそらく意図したとおりには機能しません。

リレーションシップpublic virtual ICollection<Role> Role { get; set; }を使用して、EFが行うことは、RolePersonIdに関連付けるために使用される追加フィールド(Personなど)でRolesテーブルを拡張することです。これに関する問題は明らかです。リンクPersonRoleなしでは、2人に同じRoleを与えることはできません。

1
nick_w

直接的な質問への答えではありませんが、EF命名規則を使用して、注釈を避け、エンティティクラスをクリーンに保ちます。 2つの状況を示します。

1-多くはEF命名規則を使用

役割には多くの人があり、人には1つの役割があります

1-命名規則が存在しない場所が多い(同じタイプの親子)

人には多くの創造物があり、人には1人の創造者がいます)

public class Role
{
    public int RoleId { get; set; }
    public string Name { get; set; }
    ...

    public virtual ICollection<Person> Persons { get; set; }
}

public class Person
{
    public int PersonId { get; set; }
    public int CreatorId { get; set; } 
    public int RoleId { get; set; } 
    ...

    public virtual Role Role { get; set; }
    public virtual Person Creator { get; set; }
    public virtual ICollection<Person> Created { get; set; }
}

OnModelCreatingで作成者が作成した関係の場合:

modelBuilder.Entity<Person>()
    .HasOptional(p => p.Creator)
    .WithMany(p => p.Created)
    .HasForeignKey(p => p.CreatorId);

「ClassName」+「Id」(大文字と小文字を区別)を使用すると、EFは自動的にプライマリキー/識別子であると想定します。仮想キーマッピングとPrimaryKey "RoleId"の組み合わせにより、役割と個人の関係が自動的に作成されます

1
Talon