1. 插入输入
1、只要操作Books属性,就可以向数据库中增加数据,但是通过C#代码修改Books中的数据只是修改内存中的数据。对Books做修改后,需要调用DbContext的方法SaveChange(),但是用EF Core都推荐用异步方法
- 在EF Core中,DbContext的
SaveChanges()方法
是同步的,它会阻塞当前线程直到所有更改都已保存到数据库中。如果你在应用程序中使用了大量的数据库操作,这可能会导致应用程序的性能问题。- 为了解决这个问题,EF Core还提供了异步方法,即
SaveChangesAsync()
。调用SaveChangesAsync()方法时,EF Core会将保存更改的任务异步提交到数据,这里说的异步其实就是开启一个新的线程来做这些阻塞操作。
2、EF Core默认会跟踪(Track)实体类对象以及DbSet的改变
这里有一点很奇怪,就是如果我没有加 Console.ReadKey(); 然后运行才能添加到数据库中
-
这是因为 Console.ReadKey() 方法会阻塞程序的执行,直到用户按下任意一个键,程序才会继续执行下去。如果你在执行
SaveChangesAsync()
方法之后没有加上 Console.ReadKey()进行阻塞,那么程序会跳过SaveChangesAsync()
方法执行下面的方法后立即退出,这样就没有足够的时间让 EF Core 将数据保存到数据库中。 -
如果你想要在执行 SaveChanges() 方法后等待一段时间,可以使用 Thread.Sleep() 方法来暂停程序的执行,或者使用 Console.ReadKey() 方法来等待用户按下一个键。
-
但是,这种做法并不是最好的方式,更好的做法是使用异步方法,这样可以避免程序阻塞。例如,可以使用 await context.SaveChangesAsync() 来异步保存数据到数据库中。
2. 查询数据
1、DbSet实现了IEnumberable<T>接口
,因此可以对DbSet实施Linq操作来进行数据查询。EF Core会把Linq操作转换为SQL语句。面向对象,而不是面向数据库(SQL)
TestDbContext ctx = new TestDbContext();
IEnumerable<Book> books = ctx.Books.Where(b => b.Price > 80)
Book b1 = ctx.Books.Single(b => b.Title== "零基础趣学C语言");
Book b2 = ctx.Books.FirstOrDefault(b=>b.Id==9);
可以使用OrderBy操作进行数据的排序
IEnumerable<Book> books = ctx.Books.OrderByDescending(b => b.Price);
GroupBy(分组)也可以
//先根据 AuthorName 进行分组,这里的 b 就代表每一个元素,g 就代表每一个小组
//在这段代码中,第一个b代表每个Book实体,而第二个b则代表每个分组中的每个Book实体
var groups = ctx.Books.GroupBy(b => b.AuthorName)
.Select(g => new {
AuthorName = g.Key, BooksCount = g.Count(), MaxPrice = g.Max(b => b.Price) });
foreach(var g in groups)
{
Console.WriteLine($"作者名:{
g.AuthorName},著作数量:{
g.BooksCount},最贵的价格:{
g.MaxPrice}");
}
大部分Linq操作都能作用与EF Core
3. 修改、删除
1、要对数据进行修改,首先需要把要修改的数据查询出来,然后再对查询出来的对象进行修改,然后再执行SaveChangesAsync()保存修改
TestDbContext ctx = new TestDbContext();
var b = ctx.Books.Single(b=>b.Title== "数学之美");
b.AuthorName = "Jun Wu";
await ctx.SaveChangesAsync();
2、删除也是先把要删除的数据查询出来,然后再调用DbSet或者DbContext的Remove方法把对象删除然后再执行SaveChangeAsync()保存修改。
TestDbContext ctx = new TestDbContext();
var b = ctx.Books.Single(b => b.Title