Entity Framework Core 3.1 入门(五)关联数据的添加和查询
此入门教程是记录下方参考资料视频的过程,本例基于Entity Framework Core 3.1
开发工具:Visual Studio 2019
目录
Entity Framework Core 3.1 入门(八)在 ASP.NET Core 中配置 Entity Framework Core
添加关系数据
调用DbContext的DbSet的Add()方法,然后保存即可,直接上代码
public static void Func_09()
{
using var context = new DemoContext();
var serieA = context.Leagues.Single(x => x.Name == "Serie A");
var juventus = new Club
{
//设置导航属性,扯上关系
League = serieA,
Name = "Juventus",
City = "Torino",
DateOfEstablishment = new DateTime(1897, 11, 1),
//设置导航属性,扯上关系
Players = new List<Player>
{
new Player
{
Name="C. Ronaldo",
DateOfBirth=new DateTime(1985,2,5)
}
}
};
context.Clubs.Add(juventus);
var count = context.SaveChanges();
Console.WriteLine("==============");
Console.WriteLine(count);
}
也可以从导航属性设置,然后保存
public static void Func_10()
{
using var context = new DemoContext();
//先查询出需要执行添加操作的对象
var juventus = context.Clubs.Single(x => x.Name == "Juventus");
//使用Club的Players导航属性来添加数据
//Add()方法添加关联数据,在对象的导航属性上直接添加即可
juventus.Players.Add(new Player
{
Name = "Gonzalo Higuain",
DateOfBirth = new DateTime(1987, 12, 10)
});
//保存更改
var count = context.SaveChanges();
Console.WriteLine("==============");
Console.WriteLine(count);//2,Club表和Player表添加数据
}
实际应用,模拟前端传递数据到后端
public static void Func_11()
{
using var context = new DemoContext();
var juventus = context.Clubs.Single(x => x.Name == "Juventus");
juventus.Players.Add(new Player
{
Name = "Matthijs de ligt",
DateOfBirth = new DateTime(1999, 12, 18)
});
{
//juventus相当于JSON传进来的,并且juventus中新添加的Player没主键
using var newContext = new DemoContext();
//添加追踪
newContext.Clubs.Update(juventus);
var count = newContext.SaveChanges();
Console.WriteLine("==============");
Console.WriteLine(count);//2,影响两行
//因为两个表(Club和Player)都被设置为Modified
}
}
上面的例子的Update()更改为Attach(),添加关系数据
public static void Func_12()
{
using var context = new DemoContext();
var juventus = context.Clubs.Single(x => x.Name == "Juventus");
juventus.Players.Add(new Player
{
Name = "Miralem Pjanic",
DateOfBirth = new DateTime(1990, 4, 2)
});
{
//juventus相当于JSON传进来的,并且juventus中新添加的Player没主键
using var newContext = new DemoContext();
//添加追踪,将状态设置为UnChanged
newContext.Clubs.Attach(juventus);
var count = newContext.SaveChanges();
Console.WriteLine("==============");
Console.WriteLine(count);//1,影响一行
//因为Club表未改变,状态也是UnChanged
//因为新增的Player没主键,所以DbContext知道Player表有变化
}
}
手动设置外键,添加关系数据
public static void Func_13()
{
using var context = new DemoContext();
var resume = new Resume
{
PlayerId = 1,//C. Ronaldo
Description = "..."
};
context.Resumes.Add(resume);
var count = context.SaveChanges();
Console.WriteLine("==============");
Console.WriteLine(count);//1
}
总结
查询关联数据
1.预加载,一次性把所有关联的数据预加载到DbContext
public static void Func_14()
{
using var context = new DemoContext();
//Include(),连同关联的属性对象一起查询出来
//ThenInclude(),级联添加
var clubs = context.Clubs
.Where(x => x.Id > 0)
.Include(x => x.League)
.Include(x => x.Players)
.ThenInclude(y => y.Resume)
.Include(x => x.Players)
.ThenInclude(y => y.GamePlayers)
.ThenInclude(z => z.Game)
.ToList();
//匿名类,显示需要的信息
var info = context.Clubs
.Where(x => x.Id > 0)
.Select(x => new
{
x.Id,
LeagueName = x.League.Name,
x.Name,
Player = x.Players
.Where(p =>
p.DateOfBirth > new DateTime(1990, 1, 1)),
}).ToList();
//DbContext 无法追踪匿名类,只能追踪它识别的类
//但是此例中Player可以被追踪
foreach (var data in info)
{
foreach (var player in data.Player)
{
player.Name += "~";
}
}
context.SaveChanges();
}
显式加载
public static void Func_15()
{
using var context = new DemoContext();
//显式加载缺点:不能使用Club集合加载关联数据,只能使用单个数据
var info = context.Clubs.First();
//加载关联集合
context.Entry(info)
.Collection(x => x.Players)
.Query()
.Where(x => x.DateOfBirth > new DateTime(1990, 1, 1))
.Load();
//加载关联引用
context.Entry(info)
.Reference(x => x.League)
.Load();
}
懒加载
EF Core默认关闭懒加载,这里就不演示了
懒加载也可以叫做按需加载、延迟加载。可以分两方面来理解,一方面指暂时不需要该数据,不用在当前马上加载,而可以推迟到使用它时再加载;另一方面指不确定是否将会需要该数据,所以暂时请不要加载,待确定需要后再加载它。懒加载是一种很重要的数据访问特性,可以有效地减少与数据源的交互(注意,这里所提的交互不是指交互次数,而是指交互的数据量),从而提升程序性能。