.net core EF Core調用存儲過程的方式
前言
在這里,我們將嘗試去學習一下 .net core EF Core 中調用存儲過程。
我們知道,EF Core 是不支持直接調用存儲過程的,那它又提供了什么樣的方式去執(zhí)行存儲過程呢?有如下方法:
1、FromSql,官方文檔
DbSet<TEntity>.FromSql()
2、執(zhí)行SQl命令
DbContext.Database.ExecuteSqlCommand()
但是,這兩種方式都有局限性:
1、FromSql方式的結果一定要是實體類型,就是數(shù)據(jù)庫表映射的模型。這意味著,執(zhí)行存儲過程返回的結果一定是跟數(shù)據(jù)庫表相關的所有字段;
2、FromSql方式的結果不能有關聯(lián)關系數(shù)據(jù)。這就相當于不能 join ,也返回不了 join 的關聯(lián)表的數(shù)據(jù)。
3、ExecuteSqlCommand執(zhí)行插入、更新跟刪除的存儲過程不能直接映射到實體(EF Core不支持嘛,在講 EF 跟 EF Core 的區(qū)別時已經(jīng)很清晰了),所以,CUD 方法不能直接調用 SaveChanges 方法。
我們來試試演示一下:
(1)準備一個存儲過程,一般為了方便,直接就是 DB-First,執(zhí)行以下的 SQL 腳本就OK了
USE [Library] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[proc_getbooks] @name nvarchar(50) AS BEGIN SET NOCOUNT ON; select * from books where name like @name +'%' END GO
當創(chuàng)建好了這個有傳參的有返回結果的存儲過程的時候,數(shù)據(jù)庫在可編程性下就有一個存儲過程了(這個數(shù)據(jù)庫是我專門用來做demo的)
(2)用 FromSql 調用存儲過程,由上面就可以知道它是 DbSet 的方法,而 DbSet 是可以執(zhí)行原生的 sql 語句去查詢底層的數(shù)據(jù)庫。同樣,使用 DbSet 可以執(zhí)行存儲過程,從而返回實體類型,但就是具有上面所說的局限性罷了。
//用 FromSql 調存儲過程 var name = "C"; var books = _context.Books .FromSql($"proc_getbooks {name}") .ToList(); //or 使用 exec 關鍵字調用存儲過程 //var books = _context.Books.FromSql($"exec proc_getbooks {name}").ToList(); //or 使用 SqlParameter 實例進行參數(shù)的插入 //var param = new SqlParameter() //{ // ParameterName = "@name", // SqlDbType = System.Data.SqlDbType.NVarChar, // Direction = System.Data.ParameterDirection.Input, // Size = 50, // Value = name //}; //or 使用 @p0 代表第一個參數(shù),則 @p1 就代表第二個參數(shù)等以此類推 //var books = _context.Books.FromSql("proc_getbooks @p0", name).ToList();
同樣,在這里值得一提的是,當我們多次調用同一個存儲過程,傳遞同樣的參數(shù)的時候,比如像下面:
//用 FromSql 多次調同一個存儲過程 var name = "C"; var list1 = _context.Books.FromSql($"proc_getbooks {name}").ToList(); var list2 = _context.Books.FromSql($"proc_getbooks {name}").ToList(); var list3 = _context.Books.FromSql($"proc_getbooks {name}").ToList();
所有的實體默認(可以設置)都會被 DbContext 進行跟蹤。如果你執(zhí)行同樣的存儲過程,傳同樣的參數(shù)的時候,進行多次執(zhí)行的時候,相當于執(zhí)行同樣的 sql 語句多次,但返回的結果確認一樣的, 根據(jù)DbContext 的跟蹤,直接就獲取緩存進行返回結果了。就是說,存儲過程會被調用多次,但只查了一次數(shù)據(jù)庫,其他的在緩存里拿數(shù)據(jù)。
(3)用ExecuteSqlCommand 調用存儲過程,這個跟 EF 是一個毛樣的,由于要測試的話,還要創(chuàng)建一個存儲過程,因為這個執(zhí)行查詢沒有意義,如果你看它的返回的話,都是 int 類型,而且返回結果都是影響的行數(shù)。
看看源碼:
其實 ExecuteSqlCommand 最終是調用 ExecuteNonQuery,就是執(zhí)行非查詢的語句,返回影響的行數(shù),也驗證了剛才所說的。
扯遠了,那么再創(chuàng)建一個存儲過程吧
CREATE PROCEDURE [dbo].[proc_createbook] @name Varchar(50), @author Varchar(50), @cateid int AS BEGIN SET NOCOUNT ON; Insert into books( [name] ,[author] ,[createtime] ,[isdel] ,[cateid] ) Values (@name, @author,GETDATE(),0,@cateid) END GO
創(chuàng)建后
來調用以下試試:
//用 ExecuteSqlCommand 調存儲過程, 用parameters: new[] {}也是可以的 var name = "C# 高級進階"; var author = "-"; var cateid = 1; _context.Database.ExecuteSqlCommand("proc_createbook @p0,@p1,@p2", name, author, cateid);
執(zhí)行結果:
OK,是可以執(zhí)行成功的。
到這里先完成第一部分先,接下來就做調用存儲過程的擴展,因為單靠這兩種調用方式,我們是不會滿足的!
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。
相關文章
Asp.net Core中實現(xiàn)自定義身份認證的示例代碼
這篇文章主要介紹了Asp.net Core中實現(xiàn)自定義身份認證的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-05-05ASP.NET MVC4 利用uploadify.js多文件上傳
本文主要介紹了ASP.NET MVC4利用uploadify.js實現(xiàn)多文件上傳的方法代碼。具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03.Net WebApi消息攔截器之MessageHandler的示例
這篇文章主要介紹了.Net WebApi消息攔截器之MessageHandler的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08asp.net后臺如何動態(tài)添加JS文件和css文件的引用
動態(tài)添加JS文件和css文件的引用在asp.net后臺如何實現(xiàn)呢?首先添加命名空間 using System.Web.UI.HtmlControls,之后按照下面的步驟操作即可2014-09-09使用.net?core?自帶DI框架實現(xiàn)延遲加載功能
在某些情況,我們希望能延遲一個依賴的初始化。如果使用的是autofac,我們可以通過注入Lazy來實現(xiàn),這篇文章主要介紹了使用.net?core?自帶DI框架實現(xiàn)延遲加載,需要的朋友可以參考下2023-02-02