C# 首先影响EF代码中的外键列命名(CTP5)
我有一个POCO类,它与另一个类有两个单向一元关系,两个类共享一个祖先。生成的架构中外键的名称不反映属性名称。(Properties Main Contact和Financial Contact提供PersonId和PersonId1字段名) 如何影响架构生成以生成与属性名匹配的数据库列名 模型如下所示: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
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的帖子: