• 欢迎光临~

EF Core 中的异步方法、执行SQL语句和实体的跟踪

开发技术 开发技术 2022-07-26 次浏览

EF Core 中的异步方法

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);
 }
EF Core 执行非查询原生sql语句
 --将查询出来的数据插入数据库
 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语句
    //执行实体相关的查询原生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
  //执行原生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等。

EF Core 如何判断数据发生了变化
 //只要一个实体对象和DbContext发生任何的关系(查询,add,和与DbContext有关系的其他对象产生关系)
 //都默认会被DbContext跟踪  
 User user1 = await ctx.Users.FirstAsync();//EF Core存储了一个副本(快照)
     user1.Name = "2222";
  User user2 = new User();//这状态是Detached
     await ctx.SaveChangesAsync();//此时 对象与快照的值对比 发生改变则修改
 

EF Core 中的异步方法、执行SQL语句和实体的跟踪

总结:

1.已分离(Detached)和未改变(Unchanged)的实体,SaveChangesAsync()忽略。

2.已添加的实体,SaveChangesAsync()插入数据库。

3.已修改的实体,SaveChangesAsync()更新到数据库。

4.已删除的实体,SaveChangesAsync()从数据库中删除。

EF Core 中的异步方法、执行SQL语句和实体的跟踪

 //对象的跟踪状态
 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语句,来把内存中的实体的变化更新到数据库中。

程序员灯塔
转载请注明原文链接:EF Core 中的异步方法、执行SQL语句和实体的跟踪
喜欢 (0)