原文:https://blog.csdn.net/weixin_40719943/article/details/106960285
一、EFCore更新数据有两种方式:
1.更新每一个字段(当前entity脱离了context跟踪)
场景:entity从前端传到后台,然后调用context更新,离线状态的数据更新时会将所有的字段更新一遍
var league = context.Leagues.AsNoTracking().First();
void UpdateLeague(League league){ _context.Leagues.Update(league); _context.Leagues.SaveChanges(); }
注意:可以设置全局非跟踪模式:
public ContextDemo() { ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; }
2.只更新部分修改的字段(当前entity被context跟踪)
本例leagues从context中读出来,一直被context追踪,修改了name属性,只会更新这一个字段
其中UpdateRange代码可省略,在跟踪模式下context会一直追踪这个对象,savechange的时候会自动识别需要更新的字段
var leagues = context.Leagues.Skip(1).Take(3).ToList();
foreach (var item in leagues)
{
item.Name += "_modify";
}
context.Leagues.UpdateRange(leagues);//跟踪模式下可省略,非跟踪模式下不可省略
context.SaveChanges();
注意:那么什么是跟踪模式,什么是离线模式呢?见本教程–09
二、追踪模式下,被追踪的数据,我只想更新当前表,关联属性不想更新该怎么处理?
案例:下面这段代码,用newContext更新player时,对于newContext 来说 player是离线数据,
用newContext更新player也会更新Game表和GamePlayer表的所有属性值,这对于我们来说是不必要的。
var game = context.Games
.Include(e => e.GamePlayers)
.ThenInclude(e => e.Player)
.FirstOrDefault();
var player = game.GamePlayers[0].Player;
player.Name = "newName";
{
using var newContext = new ContextDemo();
newContext.Update(player);
newContext.SaveChanges();
}
解决方案:
修改Entry属性,Entry是EFCore设置跟踪等级的
{
using var newContext = new ContextDemo();
//newContext.Update(player);
newContext.Entry(player).State = EntityState.Modified;
newContext.SaveChanges();
}