天天看點

EFCore——原生Sql語句(12)一、在EFCore的體系下執行原生SQL二、使用ADO.NET體系下執行純原生SQL

原生Sql語句

  • 一、在EFCore的體系下執行原生SQL
          • 1.執行查詢原生sql(FromSqlInterpolated)
          • 2.執行非查詢sql(ExecuteSqlInterpolatedAsync)
  • 二、使用ADO.NET體系下執行純原生SQL
          • 1.為什麼使用ADO.NET
          • 2.ADO.NET舉例

一、在EFCore的體系下執行原生SQL

1.執行查詢原生sql(FromSqlInterpolated)

1.在EFCore體系執行SQL有很大的限制,但較為友善

2.執行原生查詢Sql語句

//使用了插值函數,Article表名,
var list = await ctx.Articles.FromSqlInterpolated(@$"select * from T_Articles").ToListAsync();
           

3.執行原生Sql語句我們可以使用FromSqlInterpolated去執行,而分頁,include,過濾,排序依舊可以找EFCore實作

4.FromSqlInterpolated執行原生Sql隻能查找全部列,不能隻查找部分列

這是FromSqlInterpolated的局限性,隻能單表查詢,不能使用join例:

2.執行非查詢sql(ExecuteSqlInterpolatedAsync)

1.執行非查詢原生查詢Sql語句

例:删除

插入

在EFCore執行原生Sql有局限性,應付不了複雜的情況,那麼可以使用接下裡的最樸素的方式。

二、使用ADO.NET體系下執行純原生SQL

1.為什麼使用ADO.NET

1.FromSqlInterpolated()隻能單表查詢,但在實作報表查詢,Sql語句非常複雜,不僅要多表join,而且傳回的查詢結果不與實體對應。不能用它來查詢,是以需要一種能執行任意Sql查詢的機制。

例:就沒對應實體,就不能用FromSqlInterpolated

select Author,Count(*)from T_Books group by Author
           

2.EFCore允許把視圖或存儲過程映射為實體,是以可以把複雜查詢寫出視圖或存儲過程,然後再聲明對應的實體。并且要DbSet

//複雜查詢
	select Author,Count(*)from T_Books group by Author
	//需要搞一些這些不對應表的實體,這些不是實體,但在代碼層面上它又是實體,會非常惡心
	class BookAuthor
	{
		public string Author{get;set;}
		public int Count{get;set;}
	}
           

3.不推薦寫視圖,存儲;導緻視圖太多;非實體的DbSet;DbSet膨脹,不好維護。當遇到這種複雜查

詢的時候建議是用Ado.Net;

2.ADO.NET舉例

1.原生ADO.NET

這裡舉一個小例子,Ado自行學習

//拿到DbContext對應的底層Connection,就是由原先EFCore調Ado,變成跳過EF直接調Ado。
                //且不需要進行釋放,由DbContext釋放掉。是以是以隻要釋放Command就行
                DbConnection conn = ctx.Database.GetDbConnection();
                if (conn.State != System.Data.ConnectionState.Open)
                {
                    //判斷沒有打開就進行打開。
                    await conn.OpenAsync();
                }

                using (var cmd = conn.CreateCommand())
                {
                    #region 删除
                    //删除
                    cmd.CommandText = "DELETE FROM T_Comments WHERE id = 7;";
                    using (var reader = await cmd.ExecuteReaderAsync())
                    {
                    }
                    #endregion

                    #region 查詢
                    //要執行的Sql
                    cmd.CommandText = "select Price,Count(*) from T_Articles group by price";
                    //執行sql
                    using (var reader = await cmd.ExecuteReaderAsync())
                    {
                        //列印
                        while (await reader.ReadAsync())
                        {
                            double price = reader.GetDouble(0);
                            int count = reader.GetInt32(1);
                            Console.WriteLine($"Price{price},Count{count}");
                        }
                    }
                    #endregion
                }
           

2.Dapper

//用到的Nuget包 Install-Package Dapper -Version 2.0.123

1.dapper是一個輕量級的orm,功能沒有EFCore多,但更加容易上手,比EFCore靈活寫

2.相比ADO.NET,dapper是對上面使用到的ADO.NET操作的簡單封裝,純寫ADO.NET,Sql效率低,比較痛苦

3.舉例

//dapper就是将執行的sql,對Ado封裝成IEnumber
 var items = ctx.Database.GetDbConnection().Query<GroupArticleByPrice>("select Price,Count(*) Count from T_Articles group by price");
                foreach(var item in items)
                {
                    Console.WriteLine($"Price{item.Price},Count{item.Count}");
                }