原文:https://blog.csdn.net/weixin_40719943/article/details/106956224
一、一对多关系
以下三个类:
1 在Club中添加了League的导航属性,但是League中并没有添加对Club的引用,说明允许多个Club中添加同一个League的导航属性,League:Club=1:n
2 在Club中添加了Player集合的导航属性,说明一个Club中可以引用多个Player,但是Player中没有添加对Club的引用,说明Club:Player=1:n
3 在类中没有创建体现一对多关系的外键属性,update-database的时候,EFCore会自动创建外键
外键在多的一方创建:
League:Club=1:n, Club中有League的外键
Club:Player=1:n, Player中有Club的外键
public class League { public int Id { get; set; } public string Name { get; set; } public string Country { get; set; } }
public class Club { public Club() { Players = new List<Player>(); } public int Id { get; set; } public string Name { get; set; } public string City { get; set; } public DateTime DateOfEstablishment { get; set; } public string History { get; set; } public League League { get; set; }//导航属性 public List<Player> Players { get; set; }//导航属性 }
public class Player { public int Id { get; set; } public string Name { get; set; } public DateTime DateOfBirth { get; set; } }
二、一多一关系
1 创建Resume类,使Resume和Player是一多一的关系,在两个类中分别添加对方的导航属性和外键
public class Resume
{
public int Id { get; set; }
public string Description { get; set; }
public int PlayerId { get; set; }
public Player Player { get; set; }
}
public class Player
{
....
public int ResumeId { get; set; }
public Resume Resume { get; set; }
}
2 这两个类是一对一关系,EFCore会选择其中一个作为主体,但EFCore有时候会选错,为了保险起见,我们需要在DbContext中用Fluent API来指定这两张表的一对一关系.
在ContextDemo这个类中重写DBContext中的方法:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//指定一对一关系
modelBuilder.Entity<Resume>()
.HasOne(x => x.Player)
.WithOne(x => x.Resume)
.HasForeignKey<Resume>(x => x.PlayerId);
}
三、多对多关系
1 添加一个Game表,一个比赛可以包含多个队员player,一个player也可能参加多场game,因此Game和Player是多对多的关系;
2 EFCore配置多对多的关系,需要一个中间表,我么起名叫GamePlayer
GamePlayer中间表起到连接作用,可以理解成是一个映射表,一个Game可能会有多条GamePlayer记录,一个Player也可能有多条Game记录
Game:GamePlayer=1:n 关系
Playe:GamePlayerr=1:n 关系
3 新建Game类,GamePlayer类,修改Player类
由于Game和GamePlayer 以及Player和GamePlayer都是一对多关系
分别在Game类及Player类对GamePlayer添加集合导航属性;
在GamePlater中创建两张表的外键以及导航属性
public class GamePlayer { public int PlayerId { get; set; } public int GameId { get; set; } public Game Game { get; set; } public Player Player { get; set; } }
public class Game { public Game() { GamePlayers = new List<GamePlayer>(); } public List<GamePlayer> GamePlayers { get; set; } public int Id { get; set; } public int Round { get; set; } public DateTime? StartTime { get; set; } }
public class Player { public Player() { //初始化,避免出现空指针异常 GamePlayers = new List<GamePlayer>(); } public List<GamePlayer> GamePlayers { get; set; } ...//其他字段 }
4 多对多关系表GamePlayer没有设置主键,这张表只有两个字段,是另外两张表的主键,因此GamePlayer可以使用联合主键,在dbcontext中配置联合主键
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//为GamePlayer设置联合主键
modelBuilder.Entity<GamePlayer>().HasKey(x => new { x.PlayerId, x.GameId });
//....
}
执行
add-migration migName
update-database
生效
结束语:以上就是对一对一、一对多、多对多关系表的简单配置,不是特别全面,仅供入门参考,详细深入了解请阅读官方文档。