Entity Framework Code First と Entity Framework Migrations (4.3.0-beta1) を使用して、次のようなデータベース構造を作成したいと考えています。
次のようにモデルを定義すると:
public class Country
{
[Required]
public Guid Id { get; set; }
[Required]
[MaxLength(100)]
public string Name { get; set; }
public virtual ICollection<State> States { get; set; }
public virtual ICollection<City> Cities { get; set; }
[ForeignKey("Capital")]
public Guid? CapitalCityId { get; set; }
public virtual City Capital { get; set; }
}
public class State
{
[Required]
public Guid Id { get; set; }
[Required]
[MaxLength(100)]
public string Name { get; set; }
[Required]
public Guid CountryId { get; set; }
[Required]
public virtual Country Country { get; set; }
public virtual ICollection<City> Cities { get; set; }
[ForeignKey("Capital")]
public Guid? CapitalCityId { get; set; }
public virtual City Capital { get; set; }
}
public class City
{
[Required]
public Guid Id { get; set; }
[Required]
[MaxLength(100)]
public string Name { get; set; }
public Guid? StateId { get; set; }
public virtual State State { get; set; }
[Required]
public Guid CountryId { get; set; }
[Required]
public virtual Country Country { get; set; }
}
public class DatabaseContext : DbContext
{
public DbSet<Country> Countries { get; set; }
public DbSet<State> States { get; set; }
public DbSet<City> Cities { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Entity<City>().HasOptional(c => c.State).WithMany(s => s.Cities);
modelBuilder.Entity<City>().HasRequired(c => c.Country).WithMany(c => c.Cities);
base.OnModelCreating(modelBuilder);
}
}
移行を追加すると、次の移行コードが生成されます。
public override void Up()
{
CreateTable(
"Countries",
c => new
{
Id = c.Guid(nullable: false),
Name = c.String(nullable: false, maxLength: 100),
CapitalCityId = c.Guid(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("Cities", t => t.CapitalCityId)
.Index(t => t.CapitalCityId);
CreateTable(
"States",
c => new
{
Id = c.Guid(nullable: false),
Name = c.String(nullable: false, maxLength: 100),
CountryId = c.Guid(nullable: false),
CapitalCityId = c.Guid(),
})
.PrimaryKey(t => t.Id)
.ForeignKey("Countries", t => t.CountryId)
.ForeignKey("Cities", t => t.CapitalCityId)
.Index(t => t.CountryId)
.Index(t => t.CapitalCityId);
CreateTable(
"Cities",
c => new
{
Id = c.Guid(nullable: false),
Name = c.String(nullable: false, maxLength: 100),
StateId = c.Guid(),
CountryId = c.Guid(nullable: false),
})
.PrimaryKey(t => t.Id)
.ForeignKey("States", t => t.StateId)
.ForeignKey("Countries", t => t.CountryId)
.Index(t => t.StateId)
.Index(t => t.CountryId);
}
これにより、正しい構造が得られます。
流暢な API を使用せずにこの結果を達成できるかどうかを知りたいです。
次のように流暢な API の説明を省略した場合:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
//modelBuilder.Entity<City>().HasOptional(c => c.State).WithMany(s => s.Cities);
//modelBuilder.Entity<City>().HasRequired(c => c.Country).WithMany(c => c.Cities);
base.OnModelCreating(modelBuilder);
}
次に、Cities テーブルに 2 つの追加フィールドが作成されます。
CreateTable(
"Cities",
c => new
{
Id = c.Guid(nullable: false),
Name = c.String(nullable: false, maxLength: 100),
StateId = c.Guid(),
CountryId = c.Guid(nullable: false),
State_Id = c.Guid(),
Country_Id = c.Guid(),
})
...
しかし、流暢な API 命令は、Code First 規則を使用してすでに発見できる以上の情報を追加しているようには見えません。
この種の関係、特に流暢な API を必要としない関係を作成するためのより良い方法があるかどうかを知りたいです。
コード スニペットは gist として入手できます。