如何使用 Fluent API 创建简单的一对多关系

How to use Fluent API for creating a simple one-to-many relationship

首先让我介绍一些背景知识:我正在创建一个应处理数据库的应用程序。该数据库可能会发展(可能会添加额外的 tables/columns/constraints,但不会删除任何内容,事实上,数据库会变得越来越精细)。

我从“数据库优先”的方法开始,因此,我创建了一个 Entity Framework 图,根据 类 在 *.cs 文件中。其中两个文件是(只有一些有趣的字段):

Area.cs:

public partial class Area
{
    public Area() {  }

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

Location.cs:

public partial class Location
{
    public Location() { }

    public string Name { get; set; }
    public int Id { get; set; }
    ...
    public Nullable<int> AreaId { get; set; }
}

这是从DB的一个版本生成的,没有覆盖约束,现在想在对应的Entity Framework模型上加一个ForeignKeyConstraint

我认为应该按如下方式进行:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Area>().HasKey(t => t.Id);     // Creation of primary key
    modelBuilder.Entity<Location>().HasKey(t => t.Id); // Creation of primary key

    modelBuilder.Entity<Location>().HasRequired(n => n.AreaId)
                                   .WithMany(...)
                                   .HasForeignKey(n => n.AreaId);
    ...

这显然行不通。我缺少以下信息:

  1. 我的“Area.cs”文件不包含对Location对象的引用(因为这个版本的数据库不包含约束,这还没有被“数据库优先”添加向导),我应该添加它还是可以不添加它来解决我的问题?
  2. 我需要填写什么来代替省略号.WithMany(...)
  3. 附加问题:我知道 ForeignKey 指令。我是否应该将“Location.cs”中的 public Nullable<int> AreaId { get; set; } 替换为 [ForeignKey("AreaId")],然后是 public virtual Area Area { get; set; }

编辑
重要提示:由于“Location.cs”和“Area.cs”是自动生成的,我希望尽量减少对这些文件的更改。

下次编辑
同时我更新了我的“Location.cs”文件如下:

...
// public Nullable<int> AreaId { get; set; }

[ForeignKey("AreaId")]
public Area Area { get; set;}
....

我的OnModelCreating()已经改成了:

modelBuilder.Entity<Location>().HasRequired(n => n.Area)
                               .WithMany(...)
                               .HasForeignKey(n => n.Area);

那就只剩下要解决的省略号问题了。

另一个编辑
由于回答(甚至评论)需要很长时间,因此我决定将以下源代码行添加到我的“Area.cs”文件中:

public virtual ICollection<Location> Locations { get; set; }

然后我将省略号填写如下:

modelBuilder.Entity<Location>().HasRequired(l => l.Area)
                               .WithMany(a => a.Locations)
                               .HasForeignKey(l => l.Area);

现在只有一个问题:我怎么能提到 AreaLocation 之间的 link 应该由 Location.AreaIdArea.Id 处理(我知道Location.AreaId是外键,但是我怎么知道它指的是Area.Id)?

提前致谢

你最后一个问题的简单答案。 EF 认识到 Area.Id 是主键,因此将 Location.AreaId 连接到 Area.Id

另外,here 是一个简单的操作指南。