如何使用 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
:
Location.AreaId
是指向 Area.Id
的外键
- 一个
Area
个对象有多个 Location
个对象
- 这是为了防止删除
Area
个对象,被 Location
个对象引用。
我认为应该按如下方式进行:
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);
...
这显然行不通。我缺少以下信息:
- 我的“Area.cs”文件不包含对
Location
对象的引用(因为这个版本的数据库不包含约束,这还没有被“数据库优先”添加向导),我应该添加它还是可以不添加它来解决我的问题?
- 我需要填写什么来代替省略号
.WithMany(...)
?
- 附加问题:我知道
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);
现在只有一个问题:我怎么能提到 Area
和 Location
之间的 link 应该由 Location.AreaId
和 Area.Id
处理(我知道Location.AreaId
是外键,但是我怎么知道它指的是Area.Id
)?
提前致谢
你最后一个问题的简单答案。 EF 认识到 Area.Id
是主键,因此将 Location.AreaId
连接到 Area.Id
另外,here 是一个简单的操作指南。
首先让我介绍一些背景知识:我正在创建一个应处理数据库的应用程序。该数据库可能会发展(可能会添加额外的 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
:
Location.AreaId
是指向Area.Id
的外键
- 一个
Area
个对象有多个Location
个对象 - 这是为了防止删除
Area
个对象,被Location
个对象引用。
我认为应该按如下方式进行:
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);
...
这显然行不通。我缺少以下信息:
- 我的“Area.cs”文件不包含对
Location
对象的引用(因为这个版本的数据库不包含约束,这还没有被“数据库优先”添加向导),我应该添加它还是可以不添加它来解决我的问题? - 我需要填写什么来代替省略号
.WithMany(...)
? - 附加问题:我知道
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);
现在只有一个问题:我怎么能提到 Area
和 Location
之间的 link 应该由 Location.AreaId
和 Area.Id
处理(我知道Location.AreaId
是外键,但是我怎么知道它指的是Area.Id
)?
提前致谢
你最后一个问题的简单答案。 EF 认识到 Area.Id
是主键,因此将 Location.AreaId
连接到 Area.Id
另外,here 是一个简单的操作指南。