如何解决EF-Core Code-First表外键列缺失

时间:2019-03-20 15:41:27

标签: entity-framework entity-framework-core

我正在学习EF Core,以下是我的三个POCO:

public class County
{
    [Key]
    public int cid { get; set; }
    public string cname { get; set; }
}

public class City
{
    [Key]
    public int cid { get; set; }
    public string cname { get; set; }
}

public class People
{
    [Key]
    public int pid { get; set; }
    public string pname { get; set; }

    public int cid { get; set; }
    public City WhichCity { get; set; }

}

我希望有两个外键,但只能从City表中得到一个。除了明确为People类定义County变量外,如何进行创建(使用批注或流畅的API或其他方法)。

1 个答案:

答案 0 :(得分:1)

只需澄清一下:您不需要具有导航属性,即public City City { get; set; }即可建立关系。您唯一需要的就是外键和正确的配置。

我认为以下配置适用于您(不过未经测试):

实体

如果您愿意的话,在这里,我还特意修改了您现有的课程,以遵循C# Naming Conventions。请记住,如果您先执行代码,那意味着您可以先拥有自己的课程。您稍后会考虑持久性。实际上,我将向您展示如何通过“配置”将类的属性持久化到数据库中时重命名它们的属性。

public class County
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class City
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class People
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int CityId { get; set; }
    // Optional
    //public City City { get; set; }

    public int CountyId { get; set; }
    // Optional
    //public County County { get; set; }
}

配置

您可以使用Fluent API进行配置,而不是使用数据注释,以配置要将类映射回数据库的方式。

public class CountyConfiguration : IEntityTypeConfiguration<County>
{
    public void Configure(EntityTypeBuilder<County> builder)
    {
        builder.HasKey(x => x.Id);        // Same as using [Key]

        builder.Property(x => x.Id)
            .HasColumnName("cid");        // If you want to rename to "cid"

        builder.Property(x => x.Name)
            .IsRequired()                 // If you want to mark that field required
            .HasColumnName("cname");      // If you want to rename to "cname"

        builder.ToTable("so_county");     // If you want to rename the table
    }
}

public class CityConfiguration : IEntityTypeConfiguration<City>
{
    public void Configure(EntityTypeBuilder<City> builder)
    {
        builder.HasKey(x => x.Id);        // Same as using [Key]

        builder.Property(x => x.Id)
            .HasColumnName("cid");        // If you want to rename to "cid"

        builder.Property(x => x.Name)
            .IsRequired()                 // If you want to mark that field required
            .HasColumnName("cname");      // If you want to rename to "cname"

        builder.ToTable("so_city");       // If you want to rename the table
    }
}

public class PeopleConfiguration : IEntityTypeConfiguration<People>
{
    public void Configure(EntityTypeBuilder<People> builder)
    {
        builder.HasKey(x => x.Id);        // Same as using [Key]

        builder.Property(x => x.Id)
            .HasColumnName("pid");        // If you want to rename to "pid"

        builder.Property(x => x.Name)
            .IsRequired()                 // If you want to mark that field required
            .HasColumnName("pname");      // If you want to rename to "pname"

        // Relationship
        builder.HasOne<County>()          // People has one County
            .WithMany()                   // County has many people
            .HasForeignKey<County>(x => x.CountyId);  // Foreign key is CountyId

        builder.HasOne<City>()            // People has one City
            .WithMany()                   // City has many people
            .HasForeignKey<City>(x => x.CityId);      // Foreign key is CityId

        builder.ToTable("so_people");     // If you want to rename the table
    }
}

最后,您需要应用那些配置OnModelCreating

public class YourDbContext : DbContext
{
    public DbSet<County> Counties { get; set; }
    public DbSet<City> Cities { get; set; }
    public DbSet<People> People { get; set; }

    public YourDbContext(DbContextOptions<YourDbContext> options) : base(options) {}

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.ApplyConfiguration(new CountyConfiguration());
        builder.ApplyConfiguration(new CityConfiguration());
        builder.ApplyConfiguration(new PeopleConfiguration());
    }
}

免责声明:手动编写。未经测试。