本文章是根据 微软MVP solenovex(杨旭)老师的视频教程编写而来,再加上本身的一些理解。
视频教程地址:https://www.bilibili.com/video/BV1xa4y1v7rR
GitHub源码:https://github.com/hllive/LearnEFCore3.1前端
EFCore只能删除被Context追踪的数据,数据怎么能被追踪呢,只能先查询出来,而后操做删除方法,删除方法有四种,如代码所示;调用Remove()或RemoveRange()方法后尚未数据库执行动做,只有调用_dbContext.SaveChanges()
才会执行数据库事务操做并返回影响行数。git
[HttpDelete] public IActionResult DeleteLeague() { //先查询出来,由于只能删除被追踪的数据 var league = _dbContext.Leagues.SingleOrDefault(l => l.Country == "贵州"); if (league == null) return NotFound(); //一、单独删除方法 _dbContext.Leagues.Remove(league);//删除单个Leagues _dbContext.Remove(league);//直接在context上Remove()方法传入model,它会判断类型 //二、批量删除方法 var league2 = _dbContext.Leagues.SingleOrDefault(l => l.Country == "中国"); _dbContext.Leagues.RemoveRange(league, league2); _dbContext.RemoveRange(league, league2); //执行数据库操做 int count = _dbContext.SaveChanges(); return Ok(count); }
修改数据与删除数据有点像,也是须要被Context追踪的数据,而后才能进行修改,所追踪的对象里有个状态属性,状态设为Modify,调用SaveChanges()时才会执行相应的修改,修改某个字段后,context就知道某个字段已经被修改。github
[HttpPut] public IActionResult UpdateLeague() { //先查询出来,由于操做被追踪的数据 var league = _dbContext.Leagues.FirstOrDefault(); //修改Name属性,被追踪的league状态属性就会变为Modify league.Name += "-"; //执行数据库操做 int count = _dbContext.SaveChanges(); return Ok(count); }
根据执行结果能够看出,只修改了Name字段,这就是由于EFCore追踪的数据,League类的name值改变了,因此才执行修改Name字段。数据库
若是修改多条记录,也就是修改集合数据,这时候EFCore就会生成集合数量的UPATE的SQL语句,若是有100条数据须要修改,EFCore就会生成100条UPATE的SQL语句。这种修改方法不太适合咱们的业务场景。ide
在实际状况中,对象不必定是从数据库中查询出来的,而是由前端传入的JSON数据。这时候就不能被EFCore追踪,可使用context.Update()方法进行数据追踪ui
经过context查询出来的数据都会被EFCore变化追踪的,进行变化追踪可能会消耗大类的内存或CPU处理,若是查询量比较大,并且不须要变化追踪,能够经过
AsNoTracking()
方法使对象不被EFcore追踪,例如:_dbContext.Leagues.AsNoTracking().FirstOrDefault();
。在AsNoTracking()
后也须要执行First()或ToList()才会真正执行数据库查询。code
[HttpPut("test")] public IActionResult UpdateLeague2() { //var league = _dbContext.Leagues.AsNoTracking().FirstOrDefault(); //这里模拟前端传过来的JSON数据序列化为对象 var league = new League { Id = new Guid("EDAAEE79-78C9-43B5-A924-08D845203D11"), Name= "贵州贵阳足球联赛" }; //修改对象的属性 league.Name = league.Name.Replace("贵州贵阳", "遵义仁怀"); //让context进行追踪,并知道它已经被修改 _dbContext.Leagues.Update(league); //执行数据库操做 int count = _dbContext.SaveChanges(); return Ok(count); }
这种离线的数据(没有被追踪)使用context.Update()方法执行时,EFCore不知道那些属性或字段已经被修改那些没有被修改。这种生成的SQL语句会把全部字段都从新赋值一遍,若是没有赋值会被设置为NULL,如上图执行结果,Country属性原本没有修改,执行SQL语句时被设置为NULL
若是只想修改某一个属性的话也是能够作到的,之后再写。。。视频
博客文章能够转载,但不能够声明为原创对象