両方とも継承階層を持つエンティティ間に1対1の関係を構成しようとしています。
サンプルとして、次の最初の継承チェーンについて考えてみましょう。
[Table("A")]
public abstract class A
{
public Guid ID { get; set; }
...
}
[Table("AA")]
public class AA : A
{
...
}
[Table("AB")]
public class AB : A
{
...
}
次に、この2番目の継承チェーンについて考えます。
[Table("B")]
public abstract class B
{
public Guid ID { get; set; }
}
[Table("BA")]
public class BA : B
{
...
}
[Table("BB")]
public class BB : B
{
...
}
AAを主要なエンティティとしてAAとBAの間に1対1の関係を追加します。
[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を主要なエンティティとしてABとBBの間に1対1の関係を追加します。
[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>
{
}
このようなコードを実行すると、インデックスの作成中にバグが発生します(Entity Framework 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の間に外部キーがないことがわかります!?!
おそらく何かが足りないのですが、このサンプルの何が問題なのかわかりません。
データベースを適切に生成するために何ができるでしょうか?