实体框架和OnModelCreating()

时间:2013-05-20 17:25:25

标签: c# entity-framework-5

我正在使用代码优先方法,我正在尝试更改EF创建表的方式。我有两个简单的类:

注意:我每次都删除并重新创建数据库。这不会发生在现实世界中,但是对于测试我试图拦截创建并强制EF创建数据库我是如何构想的。

public class Person
{
  public int PersonId { get; private set; }
  public string Forename { get; set; }
}
public class Officer : Person
{
  public int OfficerId { get; private set; }
  public bool IsManager { get; set; }
}

在我的OnModelCreating()事件中,我有以下内容:

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

        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();


        modelBuilder.Entity<Person>().HasKey(x => x.PersonId);
        modelBuilder.Entity<Person>().ToTable("Person");
        modelBuilder.Entity<Officer>().HasKey<int>(x => x.OfficerId);
        modelBuilder.Entity<Officer>().ToTable("Officer");
    }

问题是在创建数据库时,它将表创建为:

表:人 PersonId INT PK Forename nvarchar(50)

表:官员 PersonId INT PK,FK IsManager BIT OfficerId INT

对我而言,这看起来是错误的,因为它不符合传统的命名约定,即TableNameId。

非常感谢任何帮助。 在此先感谢Onam。

2 个答案:

答案 0 :(得分:3)

实体框架忽略了这一行......

modelBuilder.Entity<Officer>().HasKey<int>(x => x.OfficerId);

...因为您无法单独为派生实体定义密钥,仅适用于您在此处完成的基本实体Person

modelBuilder.Entity<Person>().HasKey(x => x.PersonId);

然后,此密钥和相应的列名PersonId将用于基本实体和派生实体的所有表。 Code-First无法为派生表中的键列赋予与基表中相同的名称。

派生实体OfficerId中的Officer被视为普通标量属性,它在OfficerId INT中显示为PK而不是Officer

关于命名约定,您可以说Person PersonId,因此调用密钥{{1}}可能有意义。嗯,这更像是面向对象而不是关系和表格观点的命名约定。

答案 1 :(得分:1)

你的班级结构有点不正确。理想情况下,你应该让一个抽象类说人,然后从中派生或者只是从官员类中删除OfficerId。否则在军官表中你会将personid作为一个只是一个冗余字段的字段而你将不会使用它。 所以你可以做的是

public class PersonBase {public string ForeName{get; set;}}
public class Person : PersonBase {public int PersonId{get; set;}}
public class Officer : PersonBase{public int OfficerId{get; set;} public bool IsManager{get; set;}}

或者,如果要更改映射的EF字段的列名,可以使用[Column(Name="COLOUMN NAME")]属性