C# 我需要在 OnModelCreating(DbModelBuilder modelBuilder) 函数中添加什么来定义 Person 和 Role 之间的关系?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13755163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What do I need to add into OnModelCreating(DbModelBuilder modelBuilder) function to define relations between Person and Role?
提问by eCorke
I'm using EntityFramework version 5.0 in WinForms project, .net 4.5.
我在 WinForms 项目 .net 4.5 中使用 EntityFramework 5.0 版。
I have created 2 for me important Entities
我为我创建了 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; }
}
and dbContext class:
和 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);
}
}
please, can you help me what I need to add into OnModelCreating(DbModelBuilder modelBuilder)function to define relations between Person and Role?
拜托,你能帮我在OnModelCreating(DbModelBuilder modelBuilder)函数中添加什么来定义人员和角色之间的关系吗?
Person can have many Role(s) (but can't be null), different Persons can have same Role(s).
人可以有多个角色(但不能为空),不同的人可以有相同的角色。
Person can have one "creator" Person (can be null), different Persons can have same "creator"
人可以有一个“创造者”人(可以为空),不同的人可以有同一个“创造者”
If you could be so kind, just advise me solution :-(
如果你能如此善良,请告诉我解决方案:-(
采纳答案by klappvisor
If you want to use Fluent API for it, look at this topicfrom MSDN. You should use Many-to-Many relationship and EF will create a table required for case when Person can have many Roles and Role have many Persons. Something like this:
如果您想为此使用 Fluent API,请查看MSDN中的此主题。您应该使用多对多关系,EF 将创建一个表,当 Person 可以有很多角色并且 Role 有很多人的情况下。像这样的东西:
modelBuilder.Entity<Person>().HasMany(x => x.Roles).WithMany();
Also you can create this relationship without using Fluent API. You should create navigation property ICollection<Person> Personsin Role class and EF will create appropriate table and relationship as well.
您也可以在不使用 Fluent API 的情况下创建这种关系。您应该ICollection<Person> Persons在 Role 类中创建导航属性,EF 也会创建适当的表和关系。
回答by nick_w
Something like this should do the job:
这样的事情应该可以完成这项工作:
Create a POCO called PersonRole. This is intended to model the relationship between a Personand a Role.
创建一个名为 的 POCO PersonRole。这旨在模拟 aPerson和 a之间的关系Role。
public class PersonRole
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public Person Person { get; set; }
public Role Role { get; set; }
}
In the Personclass, replace:
在Person类中,替换:
public virtual ICollection<Role> Role { get; set; }
with:
和:
public virtual ICollection<PersonRole> PersonRoles { get; set; }
If you want to, you could add the following to the Roleclass:
如果您愿意,可以将以下内容添加到Role类中:
public virtual ICollection<PersonRole> PersonRoles { get; set; }
doing so is optional, though it may be useful if you are wishing to look at all Peoplewith a particual Role.
这样做是可选的,但如果您希望People使用特定的Role.
In the OnModelCreatingmethod, use this code to ensure that a PersonRolewill enforce non-nullable Personand Roleproperties.
在该OnModelCreating方法中,使用这个代码,以确保一个PersonRole将执行不可为空的Person和Role特性。
modelBuilder.Entity<PersonRole>().HasRequired(p => p.Person);
modelBuilder.Entity<PersonRole>().HasRequired(p => p.Role);
Edit:
编辑:
The reason for creating the PersonRolePOCO is to ensure that a Rolecan be reused across different users. Using the existing public virtual ICollection<Role> Role { get; set; }will work, but it will probably not work as intended.
创建PersonRolePOCO的原因是为了确保Role可以在不同用户之间重复使用。使用现有的public virtual ICollection<Role> Role { get; set; }将工作,但它可能不会按预期工作。
With the relationship public virtual ICollection<Role> Role { get; set; }, what EF is going to do is augment the Roletable with an additional field, e.g., PersonId, which will be used to relate a Personto their Roles. The problem with this is clear: without the linking PersonRoletable, you won't be able to give two people the same Role.
有了关系public virtual ICollection<Role> Role { get; set; },EF 要做的是Role用一个额外的字段来扩充表,例如,PersonId将用于将 aPerson与他们的Roles. 这样做的问题很明显:如果没有链接PersonRole表,您将无法为两个人提供相同的Role.
回答by Talon
Although not an answer to your question directly, use EF naming conventions to avoid Annotaions and keep your entity classes clean. I will demonstrate 2 situations:
虽然不是直接回答您的问题,但使用 EF 命名约定来避免注释并保持您的实体类清洁。我将演示两种情况:
One - Many using EF Naming Convention
一 - 许多使用 EF 命名约定
Role has Many Persons, Person has one Role
角色有很多人,人有一个角色
One - Many Where No Naming convention Exists (Parent-Child of same Type)
一 - 不存在命名约定的许多(相同类型的父子)
Person has many Created, Person has one Creator)
人有许多创造者,人有一个创造者)
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; }
}
For the Creator-Created relationship in OnModelCreating:
对于 OnModelCreating 中的 Creator-Created 关系:
modelBuilder.Entity<Person>()
.HasOptional(p => p.Creator)
.WithMany(p => p.Created)
.HasForeignKey(p => p.CreatorId);
With, "ClassName" + "Id" (case sensitive), EF will assume that it is the Primary Key / Identifier automatically. The Role-Person relationship will be created automatically due to the Virtual Mapping combined with the PrimaryKey "RoleId"
使用“ClassName”+“Id”(区分大小写),EF 将自动假定它是主键/标识符。由于虚拟映射结合主键“RoleId”,角色-人关系将自动创建

