ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

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

2022-07-27 01:03:23  阅读:170  来源: 互联网

标签:Core await Console Users EF ctx State WriteLine SQL


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();//此时 对象与快照的值对比 发生改变则修改
 ​

总结:

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

标签:Core,await,Console,Users,EF,ctx,State,WriteLine,SQL
来源: https://www.cnblogs.com/firstsaofan/p/16523212.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有