Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 首先影响EF代码中的外键列命名(CTP5)_C#_Entity Framework_Code First - Fatal编程技术网

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

C# 首先影响EF代码中的外键列命名(CTP5),c#,entity-framework,code-first,C#,Entity Framework,Code First,我有一个POCO类,它与另一个类有两个单向一元关系,两个类共享一个祖先。生成的架构中外键的名称不反映属性名称。(Properties Main Contact和Financial Contact提供PersonId和PersonId1字段名) 如何影响架构生成以生成与属性名匹配的数据库列名 模型如下所示: public class CustomerContext: DbContext { public DbSet<Organisation> Organisations { ge

我有一个POCO类,它与另一个类有两个单向一元关系,两个类共享一个祖先。生成的架构中外键的名称不反映属性名称。(Properties Main Contact和Financial Contact提供PersonId和PersonId1字段名)

如何影响架构生成以生成与属性名匹配的数据库列名

模型如下所示:

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; }
}

代码如下所示:

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; }
}
公共类CustomerContext:DbContext { 公共数据库集组织{get;set;} 公共DbSet Persons{get;set;} 模型创建时受保护的覆盖无效(ModelBuilder) { SetInitializer(新的DropCreateDatabaseAlways()); } } 公共抽象类客户 { 公共int Id{get;set;} 公共字符串名称{get;set;} } 公共类人员:客户 { 公共字符串电子邮件{get;set;} } 公营机构:顾客 { 公众人物财务联系人{get;set;} 公共人物主联系人{get;set;} } 架构如下所示:

德鲁特卡的回答
下面druttka的回答起到了作用,很高兴知道这背后是一个CTP5错误。EF还需要指定级联行为,我已经使用fluent API按照druttka给出的链接中的示例完成了这项工作。莫特萨·马纳维的一些好的读物

现在的代码是:

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; }
}
公共类CustomerContext:DbContext { 公共数据库集组织{get;set;} 公共DbSet Persons{get;set;} 模型创建时受保护的覆盖无效(ModelBuilder) { SetInitializer(新的DropCreateDatabaseAlways()); builder.Entity() .has必需(p=>p.main联系人) .有很多 .HasForeignKey(p=>p.MainContactId) .WillCascadeOnDelete(假); builder.Entity() .Property(p=>p.MainContactId) .HasColumnName(“主要联系人”); builder.Entity() .HasRequired(p=>p.FinancialContact) .有很多 .HasForeignKey(p=>p.FinancialContactId) .WillCascadeOnDelete(假); builder.Entity() .不动产(p=>p.FinancialContactId) .HasColumnName(“财务联系”); } } 公共抽象类客户 { 公共int Id{get;set;} 公共字符串名称{get;set;} } 公共类人员:客户 { 公共字符串电子邮件{get;set;} } 公营机构:顾客 { 公众人物财务联系人{get;set;} 公共int FinancialContactId{get;set;} 公共人物主联系人{get;set;} public int MainContactId{get;set;} } 现在,它提供了更合适的数据库:
默认情况下,EF代码首先使用约定优先于配置。但是,您可以通过重写DbContent.OnModelCreating来设置显式替代方案。许多例子,由ScottGu提供

编辑

所以在CTP5中,MapSingleType如前所述消失了。以下内容适用于简单的字符串属性,但不适用于组织与个人的关系。我很好奇,并计划继续研究它,但在此期间,也许这会让你开始,或者其他人可以完成答案

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

好的,我明白了。找到了答案。免责声明:我只验证了数据库架构是否按预期创建。我还没有测试播种数据或进一步的积垢操作是否如预期的那样工作

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; }
}

使用属性来反映您的数据库架构名称不正确?请告诉我我的答案中的编辑2是否适合您。正如我所说,我测试了db是否按预期创建,但没有测试进一步的CRUD操作,因此我很想知道它是否正常工作。我将尝试实际操作它,并尽快发布一个显式示例。druttka-感谢您的响应,这确实起到了作用。我已经更新了答案以显示新代码。我还必须为每个组织属性添加一个反向属性,因为我需要指定级联行为,并且我使用了fluent API版本,而不是您使用的属性。我真的很感谢你的帮助:)更新-你不需要反向属性(这很好!)。参考Morteza Manavi的帖子: