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の場合もあります)を持つことができ、異なる人は同じ「作成者」を持つことができます
あなたがとても親切である可能性がある場合は、解決策をアドバイスしてください:-(
Fluent APIを使用する場合は、MSDNの このトピック をご覧ください。多対多の関係を使用する必要があります。EFは、Personが多くのロールを持つことができ、Roleが多くの人を持つ場合に必要なテーブルを作成します。このようなもの:
modelBuilder.Entity<Person>().HasMany(x => x.Roles).WithMany();
また、Fluent APIを使用せずにこの関係を作成できます。ナビゲーションプロパティICollection<Person> Persons
をRoleクラスに作成する必要があります。EFは適切なテーブルとリレーションシップも作成します。
このような何かが仕事をする必要があります:
PersonRole
というPOCOを作成します。これは、Person
とRole
の間の関係をモデル化することを目的としています。
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が行うことは、Role
をPersonId
に関連付けるために使用される追加フィールド(Person
など)でRoles
テーブルを拡張することです。これに関する問題は明らかです。リンクPersonRole
なしでは、2人に同じRole
を与えることはできません。
直接的な質問への答えではありませんが、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"の組み合わせにより、役割と個人の関係が自動的に作成されます