第四節: EF調用存儲過程的通用寫法和DBFirst模式子類調用的特有寫法


一. 背景

   上一個章節,介紹了EF調用兩類SQL語句,主要是借助 ExecuteSqlCommand  和 SqlQuery 兩個方法來完成,在本章節主要是復習幾類存儲過程的寫法和對應的EF調用這幾類存儲過程的寫法,另外介紹EF的DBFirst模式的下EF存儲過程的特有寫法。

  本章要達到以下幾個目標:

  ① 熟練掌握存儲過程的相關概念和幾類寫法(去復習)

  ② EF各種模式調用各種存儲過程的通用寫法(也是借助  ExecuteSqlCommand  和 SqlQuery )

  ③ EF的DBFirst模式事先映射好存儲過程,簡潔調用的寫法

 

二. EF調用存儲過程

   EF調用存儲過程通用的寫法,分兩類:  

  ① 對於查詢相關的存儲過程,調用 SqlQuery 方法

  ② 對於增刪改或其他的存儲過程,調用 ExecuteSqlCommand 方法

1. 不含任何參數(查詢類的存儲過程)

   直接調用SqlQuery方法進行操作。

1 if (exists (select * from sys.objects where name = 'GetAll'))
2     drop proc GetAll
3 go
4     create proc GetAll
5 as
6     select * from TestOne;
7 
8 -- 調用
9 exec GetAll;
1       private static void NewMethod(DbContext db)
2         {
3             Console.WriteLine("---------------------------------1. 測試查詢所有數據(不含輸入參數)----------------------------------------");
4             List<TestOne> tList = db.Database.SqlQuery<TestOne>("GetAll").ToList();
5             foreach (var item in tList)
6             {
7                 Console.WriteLine("id為:{0},t1為:{1},t2為:{2}", item.id, item.t1, item.t2);
8             }
9         }

2. 含多個輸入參數(查詢類的存儲過程)

   調用SqlQuery方法進行操作,傳入參數的使用要使用SqlParameter參數化的方式進行傳入,特別注意:調用時,存儲過程的名字后面的參數 必須按照SqlParameter中的先后順序來寫

 1 if (exists (select * from sys.objects where name = 'GetALLBy'))
 2     drop proc GetALLBy
 3 go
 4     create proc GetALLBy(
 5         @id varchar(32),
 6         @t1 varchar(32)
 7     )
 8 as
 9     select * from TestOne where id=@id and t1=@t1;
10 
11 exec GetALLBy @id='1',@t1='2';
 1      private static void NewMethod2(DbContext db)
 2         {
 3             Console.WriteLine("---------------------------------2. 測試根據指定條件查詢數據(含輸入參數)----------------------------------------");
 4             SqlParameter[] para ={
 5                                            new SqlParameter("@id","1"),
 6                                            new SqlParameter("@t1","txt1")
 7                                   };
 8             //調用的時,存儲過程的名字后面的參數 必須按照SqlParameter中的先后順序來寫
 9             List<TestOne> tList = db.Database.SqlQuery<TestOne>("GetALLBy @id,@t1", para).ToList();
10             foreach (var item in tList)
11             {
12                 Console.WriteLine("id為:{0},t1為:{1},t2為:{2}", item.id, item.t1, item.t2);
13             }
14         }

3. 增刪改的存儲過程(含1個輸入參數)

   調用 ExecuteSqlCommand  方法來執行,針對輸入參數,要采用SqlParameter的方式來進行傳參數

 1 if (exists (select * from sys.objects where name = 'DoSome'))
 2     drop proc DoSome
 3 go 
 4     create proc DoSome(
 5         @id varchar(32)
 6     )
 7 as
 8     begin transaction
 9  begin try
10         truncate table [dbo].[TestOne];
11         insert into TestOne values(@id,'1','2');
12         delete from TestOne where id='2'
13     commit transaction
14  end try
15  begin catch
16     rollback transaction
17  end catch
18 
19  exec DoSome 1
  private static void NewMethod3(DbContext db)
        {
            Console.WriteLine("---------------------------------3. 測試根據指定條件查詢數據(含輸入參數)----------------------------------------");
            SqlParameter[] para ={
                                           new SqlParameter("@id",Guid.NewGuid().ToString("N")),
                                     };
            int n = db.Database.ExecuteSqlCommand("DoSome @id", para);
            if (n > 0)
            {
                Console.WriteLine("操作成功");
            }
            else
            {
                Console.WriteLine("沒有更多數據進行處理");
            }

        }

4. 帶輸出參數的存儲過程的調用

 1 GO
 2  if (exists (select * from sys.objects where name = 'GetT1Value'))
 3     drop proc GetT1Value
 4 go
 5     create proc GetT1Value(
 6         @t1 varchar(32),
 7         @count int output
 8     )
 9 as
10     select @count=count(*) from TestOne where t1=@t1;
11     select * from TestOne where t1=@t1;
12 go
13 declare @myCount int;
14 exec GetT1Value '111',@myCount output;
15 select @myCount as myCount;
 1    private static void NewMethod4(DbContext db)
 2         {
 3             Console.WriteLine("---------------------------------4. 測試查詢含有輸入和輸出操作----------------------------------------");
 4             //把輸出參數單獨拿出來聲明
 5             SqlParameter para1 = new SqlParameter("@t2", SqlDbType.Int);
 6             para1.Direction = ParameterDirection.Output;
 7             //把輸出參數放到數組里
 8             SqlParameter[] para2 ={
 9                                            new SqlParameter("@t1","111"),
10                                            para1
11                                      };
12             var tList1 = db.Database.SqlQuery<TestOne>("exec GetT1Value @t1,@t2 out", para2).ToList();
13             //通過輸出參數在數組中的位置來獲取返回值。
14             var count = para2[1].Value;
15 
16             Console.WriteLine($"數量count為:{count}");
17             foreach (var item in tList1)
18             {
19                 Console.WriteLine("id為:{0},t1為:{1},t2為:{2}", item.id, item.t1, item.t2);
20             }
21 
22         }

 PS:這種調用方式,需要先聲明一下輸出類型,然后把輸出參數放到SqlParameter這個數組里,執行完后,通過數值下標.Value來獲取這個返回值。(和DBFirst模式下調用有所不同)

 

三. DBFirst模式快捷調用存儲過程

   前面介紹的調用存儲過程的方法是通用模式,無論EF的哪種模式都可以使用,這里將介紹DBFirst模式的快捷調用,原理即創建的時候將存儲過程映射進來了,所以可以直接調用。如下圖:

 

1. 不含任何參數(查詢類存儲過程)

 1 -- 1.無參存儲過程(查詢)
 2 if (exists (select * from sys.objects where name = 'GetAll'))
 3     drop proc GetAll
 4 go
 5     create proc GetAll
 6 as
 7     select * from DBTestOne;
 8 
 9 -- 調用
10 exec GetAll;
1    private static void DBNewMethod(EFDB3Entities db)
2         {
3             Console.WriteLine("---------------------------------1. 測試查詢所有數據(不含輸入參數)----------------------------------------");
4             var tList = db.GetAll().ToList();
5             foreach (var item in tList)
6             {
7                 Console.WriteLine("id為:{0},t1為:{1},t2為:{2}", item.id, item.t1, item.t2);
8             }
9         }

2. 含多個輸入參數(查詢類存儲過程)

 1 --2. 有參數的存儲過程(查詢)
 2 if (exists (select * from sys.objects where name = 'GetALLBy'))
 3     drop proc GetALLBy
 4 go
 5     create proc GetALLBy(
 6         @id varchar(32),
 7         @t1 varchar(32)
 8     )
 9 as
10     select * from DBTestOne where id=@id and t1=@t1;
11 
12 exec GetALLBy @id='1',@t1='2';
1      private static void DBNewMethod2(EFDB3Entities db)
2         {
3             Console.WriteLine("---------------------------------2. 測試根據指定條件查詢數據(含輸入參數)----------------------------------------");
4             var tList = db.GetALLBy("11", "1").ToList();
5             foreach (var item in tList)
6             {
7                 Console.WriteLine("id為:{0},t1為:{1},t2為:{2}", item.id, item.t1, item.t2);
8             }
9         }

 3. 增刪改存儲過程(含1個輸入參數)

 1 --3. 增刪改的一組過程
 2 if (exists (select * from sys.objects where name = 'DoSome'))
 3     drop proc DoSome
 4 go 
 5     create proc DoSome(
 6         @id varchar(32)
 7     )
 8 as
 9     begin transaction
10  begin try
11         truncate table [dbo].[DBTestOne];
12         insert into DBTestOne values(@id,'1','2');
13         delete from DBTestOne where id='2'
14     commit transaction
15  end try
16  begin catch
17     rollback transaction
18  end catch
19 
20  go
21  exec DoSome 1
 1  private static void DBNewMethod3(EFDB3Entities db)
 2         {
 3             Console.WriteLine("---------------------------------3. 測試根據指定條件查詢數據(含輸入參數)----------------------------------------");
 4             int n = db.DoSome("33");
 5             if (n > 0)
 6             {
 7                 Console.WriteLine("操作成功");
 8             }
 9             else
10             {
11                 Console.WriteLine("沒有更多數據進行處理");
12             }
13 
14         }

4. 帶有輸出參數

 1  if (exists (select * from sys.objects where name = 'GetT1Value'))
 2     drop proc GetT1Value
 3 go
 4     create proc GetT1Value(
 5         @t1 varchar(32),
 6         @count int output
 7     )
 8 as
 9     select @count=count(*) from DBTestOne where t1=@t1;
10     select * from DBTestOne where t1=@t1;
11 go
12 declare @myCount int;
13 exec GetT1Value '111',@myCount output;
14 select @myCount as myCount;
 1   private static void DBNewMethod4(EFDB3Entities db)
 2         {
 3             Console.WriteLine("---------------------------------4. 測試查詢含有輸入和輸出操作----------------------------------------");
 4             //聲明一下輸出參數
 5             ObjectParameter para1 = new ObjectParameter("XXX", SqlDbType.Int);
 6 
 7             var tList1 = db.GetT1Value("1", para1).ToList();
 8             //通過.Value獲取輸出參數的值。
 9             var count = para1.Value;
10 
11             Console.WriteLine($"數量count為:{count}");
12             foreach (var item in tList1)
13             {
14                 Console.WriteLine("id為:{0},t1為:{1},t2為:{2}", item.id, item.t1, item.t2);
15             }
16 
17         }

 PS:需要先聲明ObjectParameter對象來存放輸出參數,執行完后,通過.Value即可以獲取輸出參數,輸出參數都是一個值,還沒遇到集合的(PS:歡迎補充)。

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鵬飛)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 聲     明1 : 本人才疏學淺,用郭德綱的話說“我是一個小學生”,如有錯誤,歡迎討論,請勿謾罵^_^。
  • 聲     明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM