1.SaveChanges(), SaveChangesAsync()
2.异步方法大部分是定义在Microsoft.EntityFrameworkCore这个命名空间下的EntityFrameworkCoreQueryableExtensions等类中的扩展方法,记得using
3.一些异步方法
TestDbContext ctx = new TestDbContext(); await ctx.SaveChangesAsync(); await ctx.AddAsync(new User { Name ="1" }); await ctx.AddRangeAsync(new[] { new User { Name ="2" } }); await ctx.Users.AnyAsync(u=>u.Id == 5); //之后看看 await ctx.Users.AllAsync(u=>u.Id == 5); await ctx.Users.AverageAsync(u => u.Id); await ctx.Users.CountAsync(u=>u.Id == 5); await ctx.Users.CountAsync(); await ctx.Users.FirstAsync(); await ctx.Users.ForEachAsync(u => u.Name = u.Name + "1"); await ctx.Users.LongCountAsync(); await ctx.Users.SingleAsync(); await ctx.Users.SingleOrDefaultAsync(); await ctx.Users.SumAsync(u=>u.Id); //异步循环1 一般不这样做 await foreach (var l in ctx.Leaves.AsAsyncEnumerable()) { Console.WriteLine(l.Remarks); } //异步循环2 一般不这样做 foreach (var l in await ctx.Leaves.ToListAsync()) { Console.WriteLine(l.Remarks); }
--将查询出来的数据插入数据库 insert into T_Articles(Title,Message,Price) select Title,'新闻正文xxx',Price from T_Articles where Price>=10
using (TestDbContext ctx2 = new TestDbContext()) { string tj1 = "10"; //执行非查询原生sql语句 await ctx2.Database.ExecuteSqlInterpolatedAsync(@$"insert into T_Articles(Title,Message,Price) select Title,'新闻正文xxx',Price from T_Articles where Price>={tj1}"); }
//执行实体相关的查询原生SQL语句 var users = ctx2.Users.FromSqlInterpolated(@$"select * from T_Users where Name like '%杨%'"); //可以只写必须要使用原生sql的部分 其他的对此的数据的操作可以用EF Core来完成 //用Guid来无序排序 foreach (var user in users.OrderBy(u => Guid.NewGuid())) { Console.WriteLine(user.Name); }
查询出来的要与实体列一一对应
只能单表查询,不能使用join查询,但是后续可以在查询结果后面Incluede()来,进行关联数据的获取。
//执行原生sql语句 调用Ado.Net api //拿到Context对应的底层的 Connection DbConnection coon = ctx2.Database.GetDbConnection(); if (coon.State != System.Data.ConnectionState.Open) { await coon.OpenAsync(); } using (var cmd = coon.CreateCommand()) { cmd.CommandText = @$"select Name,count(*) from T_Users"; using (var reader = await cmd.ExecuteReaderAsync()) { while (await reader.ReadAsync()) { var name = reader.GetString(0); var count = reader.GetInt32(1); Console.WriteLine($"{name}:{count}"); } } }
一般的Linq操作即可,尽量不要写原生sql
1.非查询sql用await ctx2.Database.ExecuteSqlInterpolatedAsync();
2.针对实体的sql查询用ctx2.Users.FromSqlInterpolated();
3.复杂sql查询用ADO.Net的方式获取Dapper等。
//只要一个实体对象和DbContext发生任何的关系(查询,add,和与DbContext有关系的其他对象产生关系) //都默认会被DbContext跟踪 User user1 = await ctx.Users.FirstAsync();//EF Core存储了一个副本(快照) user1.Name = "2222"; User user2 = new User();//这状态是Detached await ctx.SaveChangesAsync();//此时 对象与快照的值对比 发生改变则修改
1.已分离(Detached)和未改变(Unchanged)的实体,SaveChangesAsync()忽略。
2.已添加的实体,SaveChangesAsync()插入数据库。
3.已修改的实体,SaveChangesAsync()更新到数据库。
4.已删除的实体,SaveChangesAsync()从数据库中删除。
//对象的跟踪状态 using TestDbContext ctx = new TestDbContext(); Book[] books = ctx.Books.Take(3).ToArray(); Book b1 = books[0]; Book b2 = books[1]; Book b3 = books[2]; Book b4 = new Book { Title = "零基础趣学C语言", AuthorName = "老杨" }; Book b5 = new Book { Title = "百年孤独", AuthorName = "马尔克斯" }; b1.Title = "abc"; ctx.Remove(b3); ctx.Add(b4); EntityEntry entry1 = ctx.Entry(b1); EntityEntry entry2 = ctx.Entry(b2); EntityEntry entry3 = ctx.Entry(b3); EntityEntry entry4 = ctx.Entry(b4); EntityEntry entry5 = ctx.Entry(b5); Console.WriteLine("b1.State:" + entry1.State); Console.WriteLine("b1.DebugView:" + entry1.DebugView.LongView); Console.WriteLine("b2.State:" + entry2.State); Console.WriteLine("b3.State:" + entry3.State); Console.WriteLine("b4.State:" + entry4.State); Console.WriteLine("b5.State:" + entry5.State);
DbContext会根据跟踪的实体的状态,在调用SaveChangesAsync的时候,根据实体状态的不同,生成Update,Delete,Insert等SQL语句,来把内存中的实体的变化更新到数据库中。