首先影响EF代码中的外键列命名(CTP5)

时间:2011-02-22 19:36:52

标签: c# entity-framework code-first

我有一个POCO类,它与另一个类有两个单向一元关系,两个类共享一个祖先。生成的模式中的外键名称不反映属性名称。 (属性MainContact和FinancialContact给出PersonId和PersonId1字段名称。)

如何影响模式生成以生成与属性名称匹配的数据库列名?

该模型如下所示:

The class model

代码如下所示:

public class CustomerContext: DbContext
{
   public DbSet<Organisation> Organisations { get; set; }
   public DbSet<Person> Persons { get; set; }

   protected override void OnModelCreating(ModelBuilder builder)
   {
      DbDatabase.SetInitializer(new DropCreateDatabaseAlways<CustomerContext>());
   }
}

public abstract class Customer
{
   public int Id { get; set; }
   public string Name { get; set; }
}

public class Person : Customer
{
   public string Email { get; set; }
}

public class Organisation : Customer
{
   public Person FinancialContact { get; set; }
   public Person MainContact { get; set; }
}

架构如下所示: enter image description here

来自druttka的回答


下面的druttka的答案完成了这项工作,很高兴知道这是一个CTP5错误。 EF还需要指定级联行为,并且我使用了流畅的API来执行此操作,遵循druttka给出的链接中的示例。来自Morteza Manavi here的一些更好的阅读。

现在的代码是:

public class CustomerContext : DbContext
{
   public DbSet<Organisation> Organisations { get; set; }
   public DbSet<Person> Persons { get; set; }

   protected override void OnModelCreating(ModelBuilder builder)
   {
      DbDatabase.SetInitializer(new DropCreateDatabaseAlways<CustomerContext>());

      builder.Entity<Organisation>()
         .HasRequired(p => p.MainContact)
         .WithMany()
         .HasForeignKey(p => p.MainContactId)
         .WillCascadeOnDelete(false);
      builder.Entity<Organisation>()
         .Property(p => p.MainContactId)
         .HasColumnName("MainContact");

      builder.Entity<Organisation>()
         .HasRequired(p => p.FinancialContact)
         .WithMany()
         .HasForeignKey(p => p.FinancialContactId)
         .WillCascadeOnDelete(false);
      builder.Entity<Organisation>()
         .Property(p => p.FinancialContactId)
         .HasColumnName("FinancialContact");
   }
}

public abstract class Customer
{
   public int Id { get; set; }
   public string Name { get; set; }
}

public class Person : Customer
{
   public string Email { get; set; }
}

public class Organisation : Customer
{
   public Person FinancialContact { get; set; }
   public int FinancialContactId { get; set; }

   public Person MainContact { get; set; }
   public int MainContactId { get; set; }
}

现在提供了更合适的数据库: enter image description here

1 个答案:

答案 0 :(得分:10)

EF Code First默认使用约定优于配置。但是,您可以通过覆盖DbContent.OnModelCreating来设置显式替代方案。许多例子here,由ScottGu提供。

修改

所以在CTP5中,MapSingleType像here所描述的那样消失了。以下适用于简单字符串属性,但不适用于您的组织与人员之间的关系。我很好奇,并打算继续关注它,但与此同时,也许这会让你开始或其他人可以完成答案。

public class Person : Customer
{
    [Column(Name="EmailAddress")]
    public string Email { get; set; }
}

编辑2

好的,这就搞定了。找到了答案here。免责声明:我只验证了数据库架构是按预期创建的。我没有测试播种数据或进一步的CRUD操作按预期工作。

public class Organisation : Customer
{
    [Column(Name = "FinancialContact")]
    public int? FinancialContactId { get; set; }
    [ForeignKey("FinancialContactId")]
    public Person FinancialContact { get; set; }
    [Column(Name = "MainContact")]
    public int? MainContactId { get; set; }
    [ForeignKey("MainContactId")]
    public Person MainContact { get; set; }
}