本文章是根據 微軟MVP solenovex(楊旭)老師的視頻教程編寫而來,再加上本身的一些理解。
視頻教程地址:https://www.bilibili.com/video/BV1xa4y1v7rR
GitHub源碼:https://github.com/hllive/LearnEFCore3.1html
Model之間的【多對多】【一對多】【 一對一】的關係怎麼設定,或者說數據表之間的【多對多】【一對多】【 一對一】的關係怎麼設定;git
咱們先講一下這些字段或者叫屬性,它們的屬性怎麼設定,好比說這個name這個屬性,它在數據庫中的字段類型是NVARCHAR(MAX)
,而實際上它的長度應該有必定限制,好比要求長度不超過100,那可使用DataAnnotations的attribute[Maxlength(100)]
github
使用DataAnnotations須要在Nuget中安裝System.ComponentModel.Annotations包數據庫
再執行遷移命令生成新的遷移文件mvc
add-migration changePlayerColumb
生成成功後再執行ide
Update-Database
將數據庫更新爲指定的遷移
其餘更多特性請參考:http://www.javashuo.com/article/p-gbpwtksc-nc.html支持的完整特性列表ui
如下三個Model都是一對多的關係
Club能夠看到有一個導航屬性League,導航到一個單個的League上面,因此說每一個Club都對應一個League,而這個每一個Club對應的League他有多是同一個,因此說一個League就可能對應多個Club,這樣就體現了一對多的關係,只在Club一個類裏體現就能夠了
既然有了這種一對多的關係,那麼在子表也就是Club表裏或者是Club的Model裏邊兒應該有一個字段是叫外鍵,實際上在類Club中沒有,在數據庫Club外鍵中是有LeagueId。在C#類中沒有寫LeagueId,EFCore會生成一個LeagueId外鍵,咱們也能夠在類中手動寫出來一個屬性,手動指定,也能夠不寫,不寫的話EFCore會自動生成一個
Club和Player之間的一對多關係是怎麼體現的呢,Club裏的最後一個屬性也是這種導航屬性不過是另一種形式的導航屬性,上面的League至關因而對單個的League,而對這個Player導航屬性的類型是一個集合,因此說呢?這至關於另一個方向了,這個時候club是主表,而後Player是子表。
3d
在三個Model的基礎上再建一個Model,叫比賽Game,就是每一個隊員一個賽季可能要參加不少比賽,而每一個比賽也有不少隊員同時去參加,因此說這個隊員和比賽之間就應該是多對多的關係(M:N),咱們使用CFCore是沒法直接實現多對多的關係
能夠加一箇中間表叫GamePlayer,好比說一個隊員他本賽季參加了五場比賽那麼它就應該是對應的五個GamePlayer一對多的關係,它倆之間是一對多的關係1:M,每場比賽又有多個隊員去參加,每一個隊員就至關於這場比賽的一個GamePlayer,因此說這個比賽和GamePlayer之間也是一對多的關係,這樣隊員和這個比賽之間就至關於間接地造成了一個這個多對多的關係。
code
public class Game { public Game() { GamePalyers = new List<GamePlayer>(); } public Guid Id { get; set; } public int Round { get; set; }//比賽階段 public DateTimeOffset? StartTime { get; set; }//開始時間 public List<GamePlayer> GamePalyers { get; set; } }
public class GamePlayer { public Guid PlayerId { get; set; } public Guid GameId { get; set; } //這裏也能夠體現一對多的關係 public Game Game { get; set; } public Player Player { get; set; } }
最後設定聯合主鍵,必須手動設定,在DbContext中設定,能夠override OnModelCreating()
設定好後執行遷移命令視頻
Add-Migration AddMage
執行更新數據庫
Update-Database
假設每一個隊員只能有一份簡歷,而後這一份簡歷呢,就屬於這一個隊員,因此這就屬於一對一的關係
建立一個Resume類
//簡歷 public class Resume { public Guid Id { get; set; } [MaxLength(200)] public string Description { get; set; } public Guid PlayerId { get; set; }//Player外鍵 public Player Player { get; set; }//Player導航屬性 }
在Player類中添加簡歷屬性,這樣就能實現Resume和Player類的一對一關係
這時候EFCore會選擇其中一個類做爲主表,可是EFCore可能會選錯,因此仍是須要手動指定主外鍵
在DbContext中的OnModelCreating()方法中添加
protected override void OnModelCreating(ModelBuilder modelBuilder) { //設置聯合主鍵 modelBuilder.Entity<GamePlayer>().HasKey(x => new { x.PlayerId, x.GameId }); modelBuilder.Entity<Resume>() .HasOne(x => x.Player)//一個Resume擁有一個Player .WithOne(x => x.Resume)//每一個Player又帶了一個Resume .HasForeignKey<Resume>(x => x.PlayerId);//Resume上又帶了一個外鍵PlayerId }
設定好後執行遷移命令<
Add-Migration AddResumeToOnePlayer
執行更新數據庫
Update-Database
若是執行遇到如下錯誤:請注意默認項目須要選擇Data項目
博客文章能夠轉載,但不能夠聲明爲原創