我正在尝试在具有继承层次结构的实体之间配置一对一的关系。
对于示例,让我们考虑以下第一个继承链:
[Table("A")]
public abstract class A
{
public Guid ID { get; set; }
...
}
[Table("AA")]
public class AA : A
{
...
}
[Table("AB")]
public class AB : A
{
...
}
然后,考虑第二个继承链:
[Table("B")]
public abstract class B
{
public Guid ID { get; set; }
}
[Table("BA")]
public class BA : B
{
...
}
[Table("BB")]
public class BB : B
{
...
}
在 AA 和 BA 之间添加一对一的关系,以 AA 作为主要实体:
[Table("AA")]
public class AA : A
{
...
public BA BAChild { get; set; }
...
}
[Table("BA")]
public class BA : B
{
...
public AA Parent { get; set; }
...
}
public class AAConfiguration : EntityTypeConfiguration<AA>
{
public AAConfiguration()
{
this.HasRequired(o => o.BAChild)
.WithRequiredPrincipal(o => o.Parent);
}
}
在 AB 和 BB 之间添加一对一的关系,以 AB 作为主要实体:
[Table("AB")]
public class AB : A
{
...
public BB BBChild { get; set; }
...
}
[Table("BB")]
public class BB : B
{
...
public AB Parent { get; set; }
...
}
public class ABConfiguration : EntityTypeConfiguration<AB>
{
public ABConfiguration()
{
this.HasRequired(o => o.BBChild)
.WithRequiredPrincipal(o => o.Parent);
}
}
我还希望 EF 为实体 A 和 B 生成表,因此我添加并注册了以下空 EntityTypeConfiguration :
public class AConfiguration : EntityTypeConfiguration<A>
{
}
public class BConfiguration : EntityTypeConfiguration<B>
{
}
如果您像这样运行代码,您将在创建索引期间遇到错误(升级到实体框架 4.3.1 后看到未处理的异常)
所以让我们做一些棘手的代码并注册一个从 SqlServerMigrationSqlGenerator 派生的自定义 MigrationSqlGenerator 以避免根据我的业务命名规则创建索引:
public class Configuration : DbMigrationsConfiguration<DataContext>
{
public Configuration()
{
...
this.SetSqlGenerator("System.Data.SqlClient", new CustomSqlServerGenerator());
...
}
}
public class CustomSqlServerGenerator : SqlServerMigrationSqlGenerator
{
protected override void Generate(CreateIndexOperation createIndexOperation)
{
if (createIndexOperation.Columns.Count() == 1 && createIndexOperation.Columns.Any(o => o == "ID"))
return;
base.Generate(createIndexOperation);
}
}
public class DataContext : DbContext
{
static DataContext()
{
Database.SetInitializer<DataContext>(new MigrateDatabaseToLatestVersion<DataContext, Configuration>());
}
...
}
所以现在是时候生成数据库了,我使用以下代码:
...
DataContext dataContext = new DataContext();
dataContext.Database.Initialize(true);
...
现在,如果您查看生成的数据库,您将看到表 BA 和 BB 都有表 AB 的外键,而 BA 和 AA 之间没有外键!?!
我可能遗漏了一些东西,但我看不出这个样本有什么问题。
可以做些什么来正确生成数据库?