我在WinForms项目中使用EntityFramework 5.0版.net 4.5。
我为我创建了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);
}
}
拜托,您能帮我解决一下我需要添加到OnModelCreating(DbModelBuilder modelBuilder)
函数中以定义人与角色之间关系的内容吗?
人可以有很多角色(但不能为空),不同的角色可以有相同的角色。
人可以拥有一个“创造者”人(可以为空),不同的人可以拥有相同的“创造者”
如果你可以这么善良,请告诉我解决方案: - (
答案 0 :(得分:16)
如果您想使用Fluent API,请查看MSDN中的this topic。您应该使用多对多关系,EF将创建一个表所需的表,当Person可以有多个角色和角色有很多人时。像这样:
modelBuilder.Entity<Person>().HasMany(x => x.Roles).WithMany();
您也可以在不使用Fluent API的情况下创建此关系。您应该在Role类中创建导航属性ICollection<Person> Persons
,EF也将创建适当的表和关系。
答案 1 :(得分:1)
这样的事情应该可以胜任:
创建一个名为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
强制执行不可为空的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
表,该字段将用于关联{{1}他们的Person
。这个问题很明显:如果没有链接Roles
表,您将无法为两个人提供相同的PersonRole
。
答案 2 :(得分:1)
虽然不能直接回答您的问题,但请使用EF命名约定来避免Annotaions并保持实体类的清洁。 我将演示两种情况:
One - 许多人使用EF命名惯例
角色有很多人,人有一个角色
一个 - 许多没有命名约定存在(相同类型的父子)
人有很多创造,人有一个创造者)
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中的Creator-Created关系:
modelBuilder.Entity<Person>()
.HasOptional(p => p.Creator)
.WithMany(p => p.Created)
.HasForeignKey(p => p.CreatorId);
使用“ClassName”+“Id”(区分大小写),EF将自动假定它是主键/标识符。 由于虚拟映射与PrimaryKey“RoleId”
结合,将自动创建角色 - 人员关系