1

使用 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);

}

这会导致正确的结构。

我想知道是否可以在不使用 fluent 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 表中创建两个附加字段:

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获得。

4

0 回答 0