我需要在OnModelCreating(DbModelBuilder模型构建器)函数中添加什么来定义Person和Role之间的关系?

时间:2012-12-07 00:36:33

标签: c# entity-framework entity-framework-5 dbcontext

我在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)函数中以定义人与角色之间关系的内容吗?

人可以有很多角色(但不能为空),不同的角色可以有相同的角色。

人可以拥有一个“创造者”人(可以为空),不同的人可以拥有相同的“创造者”

如果你可以这么善良,请告诉我解决方案: - (

3 个答案:

答案 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。这是为了模拟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强制执行不可为空的PersonRole属性。

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”

结合,将自动创建角色 - 人员关系