本文介绍了在Entity Framework Code First中为同一个表定义多个外键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 MVC 应用程序中有两个实体,我使用实体框架 6 代码优先方法填充了数据库.Student 实体中有两个城市 id;其中一个用于 BirthCity,另一个用于 WorkingCity.当我在上面定义外键时,会在迁移后在 Student 表中创建一个名为 City_ID 的额外列.是否有错误或如何定义这些 FK?提前致谢.

I have two entities in my MVC application and I populated the database with Entity Framework 6 Code First approach. There are two city id in the Student entity; one of them for BirthCity, the other for WorkingCity. When I define the foreign keys as above an extra column is created named City_ID in the Student table after migration. Id there a mistake or how to define these FKs? Thanks in advance.

学生:

public class Student
{
    public int ID { get; set; }

    public string Name { get; set; }

    public string Surname { get; set; }

    public int BirthCityID { get; set; }

    public int LivingCityID { get; set; }


    [ForeignKey("BirthCityID")]
    public virtual City BirthCity { get; set; }

    [ForeignKey("LivingCityID")]
    public virtual City LivingCity { get; set; }
}


城市:

public class City
{
    public int ID { get; set; }

    public string CityName { get; set; }


    public virtual ICollection<Student> Students { get; set; }
}

推荐答案

要实现你想要的,你需要提供一些额外的配置.Code First 约定可以识别双向关系,但不是当有两个实体之间的多个双向关系.您可以添加配置(使用数据注释Fluent API)来呈现此模型构建器的信息.使用数据注释,您将使用注释称为 InverseProperty.使用 Fluent API,您将使用 Has/With 方法的组合来指定这些关系的正确端.

To achieve what you want you need to provide some aditional configuration.Code First convention can identify bidirectional relationships, but not when there aremultiple bidirectional relationships between two entities.You can add configuration (using Data Annotations or the Fluent API) to present thisinformation to the model builder. With Data Annotations, you’ll use an annotationcalled InverseProperty. With the Fluent API, you’ll use a combination of the Has/With methods to specify the correct ends of these relationships.

使用数据注释可能是这样的:

public class Student
{
  public int ID { get; set; }

  public string Name { get; set; }

  public string Surname { get; set; }

  public int BirthCityID { get; set; }

  public int LivingCityID { get; set; }


  [ForeignKey("BirthCityID")]
  [InverseProperty("Students")]
  public virtual City BirthCity { get; set; }

  [ForeignKey("LivingCityID")]
  public virtual City LivingCity { get; set; }
}

通过这种方式,您明确指定要将 BirthCity 导航属性与关系另一端的 Students 导航属性相关联.

This way you specifying explicitly that you want to relate the BirthCity navigation property with Students navigation property in the other end of the relationship.

使用 Fluent Api 可能是这样的:

Using Fluent Api could be like this:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     modelBuilder.Entity<Student>().HasRequired(m => m.BirthCity)
                                 .WithMany(m => m.Students).HasForeignKey(m=>m.BirthCityId);
     modelBuilder.Entity<Student>().HasRequired(m => m.LivingCity)
                                 .WithMany().HasForeignKey(m=>m.LivingCityId);
}

使用最后一个解决方案,您无需使用任何属性.

With this last solution you don't need to use any attibute.

现在,@ChristPratt 的建议在您的 City 类中为每个关系设置一个 Student 集合真的很有用.如果你这样做,那么使用数据注释的配置可能是这样的:

Now, the suggestion of @ChristPratt in have a collection of Student in your City class for each relationship is really useful. If you do that, then the configurations using Data Annotations could be this way:

public class Student
{
  public int ID { get; set; }

  public string Name { get; set; }

  public string Surname { get; set; }

  public int BirthCityID { get; set; }

  public int LivingCityID { get; set; }


  [ForeignKey("BirthCityID")]
  [InverseProperty("BirthCityStudents")]
  public virtual City BirthCity { get; set; }

  [ForeignKey("LivingCityID")]
  [InverseProperty("LivingCityStudents")]
  public virtual City LivingCity { get; set; }
}

或者使用 Fluent Api 遵循相同的想法:

Or using Fluent Api following the same idea:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     modelBuilder.Entity<Student>().HasRequired(m => m.BirthCity)
               .WithMany(m => m.BirthCityStudents).HasForeignKey(m=>m.BirthCityId);
     modelBuilder.Entity<Student>().HasRequired(m => m.LivingCity)
               .WithMany(m => m.LivingCityStudents).HasForeignKey(m=>m.LivingCityId);
}

这篇关于在Entity Framework Code First中为同一个表定义多个外键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 06:46