本文章是根據 微軟MVP solenovex(楊旭)老師的視頻教程編寫而來,再加上本身的一些理解。
視頻教程地址:https://www.bilibili.com/video/BV1xa4y1v7rR
GitHub源碼:https://github.com/hllive/LearnEFCore3.1html
在第3章第2節-表之間關係能夠看出
一個聯賽擁有多個俱樂部,聯賽(League)和俱樂部(Club)是一對多關係,
一個俱樂部擁有多個隊員,俱樂部(Club)和隊員(Player)是一對多關係。
首先添加一個俱樂部,俱樂部應該是添加到一個現有的聯賽中。能夠先查出來一個聯賽,而後在聯賽中添加一個俱樂部。
經過3個Model能夠看出,聯賽(League)中體現不出聯賽與俱樂部之間的關係,而在俱樂部(Club)中有聯賽(League)的導航屬性,這樣就能夠把一個Club中的League屬性設爲已知的League,這樣就把club和league關聯起了。git
舉個例子更清晰:如今有個聯賽叫《第一季度足球聯賽》,邀請全國全部地區的足球隊參加;看到邀請後,新成立一個俱樂部叫《新智聯足球隊》,成立俱樂部後須要隊員加入啊,這裏就添加了兩個隊員(王建國和李剛)github
[HttpPost("Club")] public IActionResult SaveClub() { //一、經過邀請碼獲取一個聯賽,叫《第一季度足球聯賽》 League league = _dbContext.Leagues.SingleOrDefault(l => l.Id == new Guid("4227506d-05e4-47a2-b94f-08d8451d5dc00")); //二、建立一個俱樂部 var club = new Club { //三、將獲取的聯賽添加到俱樂部中 League = league,//這樣League和Club就關聯上了 //四、設置其餘屬性 Name = "新智聯足球隊", City = "貴州省貴陽市", DateOfEstablishment = new DateTime(2020, 8, 23), History = "參加不少比賽", //五、添加隊員 Players=new List<Player>() { new Player{ Name="王建國",Birth=new DateTime(1994,8,2) }, new Player{ Name="李剛",Birth=new DateTime(1994,9,25) } } }; //添加和保存 _dbContext.Clubs.Add(club); int count = _dbContext.SaveChanges(); return Ok(count); }
經過dbContext中DbSet的Add()方法把新成立的俱樂部添加到Context中,這樣Context就知道已經新添加了一個Club,而後調用SaveChange()方法就會執行數據庫的Insert語句
最終這個例子須要瞭解League和Club怎麼關聯,Playe和Club怎麼關聯sql
再查看一個例子數據庫
[HttpPost("GamePlayer")] public IActionResult GamePlayer() { //一、查詢符合添加的隊員 var players = _dbContext.Players.Where(p => p.Birth > new DateTime(1995, 1, 1)).ToList(); //二、建立比賽對象 var game = new Game { Round = 2, StartTime = new DateTime(2020, 5, 1), //三、將查詢出來的隊員集合與比賽創建關係 GamePalyers = players.Select(p => new GamePlayer { Player = p }).ToList() }; //添加和保存 _dbContext.Games.Add(game); int count = _dbContext.SaveChanges(); return Ok(count); }
再看一個例子:如今俱樂部成立後才兩個隊員,須要再添加隊員;那麼添加單個隊員怎麼添加呢?請看代碼ide
先從數據庫中把俱樂部查出來,因爲俱樂部裏有一個Players集合屬性導航,能夠經過這個Players中的Add()方法來添加新的隊員。而俱樂部被contact變化追蹤的,因此添加一個新的隊員,context就知道這個隊員是新加的。而且不用設定外鍵,而後呢,咱們SaveChange就能夠了,由於context會把這些變化都瞭解到,而後計算出來應該執行哪些sql語句。ui
[HttpPost("Palyer")] public IActionResult AddPalyer() { //一、查詢出俱樂部 var club = _dbContext.Clubs.SingleOrDefault(l => l.Name == "新智聯足球隊"); //二、在俱樂部中添加隊員 club.Players.Add(new Player() { Name = "張全蛋", Birth = new DateTime(1999, 12, 1) }); //三、保存數據 int count = _dbContext.SaveChanges(); return Ok(count); }
首先經過一個例子能夠看出,《一、查詢出俱樂部(不追蹤)》就至關因而離線數據,不被context追蹤,使用離線數據須要使用Update方法;在使用Update的時候Context發如今俱樂部中新添加了一個隊員。3d
[HttpPost("UseAttach")] public IActionResult UseAttach() { //一、查詢出俱樂部(不追蹤) var club = _dbContext.Clubs.AsNoTracking().SingleOrDefault(x => x.Name == "新智聯足球隊"); //二、在查詢出來的俱樂部中添加新隊員 club.Players.Add(new Player { Name = "陳浩傑", Birth = new DateTime(2000, 5, 6) }); //三、使用Update更新數據 _dbContext.Clubs.Update(club);//離線數據須要使用Update方法 //四、保存數據 int count = _dbContext.SaveChanges(); return Ok(count); }
使用SaveChange()執行的SQL語句裏包括查詢Club、更新Club和添加Player的操做,使用Update()方法會把俱樂部全部屬性值從新更新一下;
咱們只是想添加一個新隊員,可是把俱樂部(Club)全部的屬性都更新了一遍。這種狀況怎麼辦呢?code
使用Attach附加方法,在Club上附加對象,這時候Club是未修改狀態,context不會進行修改操做,可是發如今Player導航屬性中新添加了一個隊員,context會對新添加的隊員生成SQL語句;說明在Club上附加了一個新隊員,因此生成SQL語句的時候只插入了隊員的數據,Club和Player之間的關係也會自動生成視頻
在上面的例子中,只須要把Update()方法修改成Attach()方法便可
[HttpPost("UseAttach")] public IActionResult UseAttach() { //一、查詢出俱樂部(不追蹤) var club = _dbContext.Clubs.AsNoTracking().SingleOrDefault(x => x.Name == "新智聯足球隊"); //二、在查詢出來的俱樂部中添加新隊員 club.Players.Add(new Player { Name = "陳浩傑", Birth = new DateTime(2000, 5, 6) }); //三、使用Update更新數據 //_dbContext.Clubs.Update(club);//離線數據須要使用Update方法 _dbContext.Clubs.Attach(club);//附加對象 //四、保存數據 int count = _dbContext.SaveChanges(); return Ok(count); }
博客文章能夠轉載,但不能夠聲明爲原創