第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法
一. 背景
? 上一個(gè)章節(jié),介紹了EF調(diào)用兩類(lèi)SQL語(yǔ)句,主要是借助 ExecuteSqlCommand??和 SqlQuery 兩個(gè)方法來(lái)完成,在本章節(jié)主要是復(fù)習(xí)幾類(lèi)存儲(chǔ)過(guò)程的寫(xiě)法和對(duì)應(yīng)的EF調(diào)用這幾類(lèi)存儲(chǔ)過(guò)程的寫(xiě)法,另外介紹EF的DBFirst模式的下EF存儲(chǔ)過(guò)程的特有寫(xiě)法。
本章要達(dá)到以下幾個(gè)目標(biāo):
?、?熟練掌握存儲(chǔ)過(guò)程的相關(guān)概念和幾類(lèi)寫(xiě)法(去復(fù)習(xí))
② EF各種模式調(diào)用各種存儲(chǔ)過(guò)程的通用寫(xiě)法(也是借助 ?ExecuteSqlCommand??和 SqlQuery?)
?、?EF的DBFirst模式事先映射好存儲(chǔ)過(guò)程,簡(jiǎn)潔調(diào)用的寫(xiě)法
?
二. EF調(diào)用存儲(chǔ)過(guò)程
? EF調(diào)用存儲(chǔ)過(guò)程通用的寫(xiě)法,分兩類(lèi):
?、?對(duì)于查詢(xún)相關(guān)的存儲(chǔ)過(guò)程,調(diào)用 SqlQuery 方法
?、?對(duì)于增刪改或其他的存儲(chǔ)過(guò)程,調(diào)用?ExecuteSqlCommand 方法
1. 不含任何參數(shù)(查詢(xún)類(lèi)的存儲(chǔ)過(guò)程)
? 直接調(diào)用SqlQuery方法進(jìn)行操作。
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 -- 調(diào)用 9 exec GetAll; 1 private static void NewMethod(DbContext db) 2 { 3 Console.WriteLine("---------------------------------1. 測(cè)試查詢(xún)所有數(shù)據(jù)(不含輸入?yún)?shù))----------------------------------------"); 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. 含多個(gè)輸入?yún)?shù)(查詢(xún)類(lèi)的存儲(chǔ)過(guò)程)
? 調(diào)用SqlQuery方法進(jìn)行操作,傳入?yún)?shù)的使用要使用SqlParameter參數(shù)化的方式進(jìn)行傳入,特別注意:調(diào)用時(shí),存儲(chǔ)過(guò)程的名字后面的參數(shù) 必須按照SqlParameter中的先后順序來(lái)寫(xiě)。
1 if (exists (select * from sys.objects where name = 'GetALLBy'))2 drop proc GetALLBy3 go4 create proc GetALLBy(5 @id varchar(32),6 @t1 varchar(32)7 )8 as9 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. 測(cè)試根據(jù)指定條件查詢(xún)數(shù)據(jù)(含輸入?yún)?shù))----------------------------------------");4 SqlParameter[] para ={5 new SqlParameter("@id","1"),6 new SqlParameter("@t1","txt1")7 };8 //調(diào)用的時(shí),存儲(chǔ)過(guò)程的名字后面的參數(shù) 必須按照SqlParameter中的先后順序來(lái)寫(xiě)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. 增刪改的存儲(chǔ)過(guò)程(含1個(gè)輸入?yún)?shù))
? 調(diào)用?ExecuteSqlCommand ?方法來(lái)執(zhí)行,針對(duì)輸入?yún)?shù),要采用SqlParameter的方式來(lái)進(jìn)行傳參數(shù)
1 if (exists (select * from sys.objects where name = 'DoSome'))2 drop proc DoSome3 go 4 create proc DoSome(5 @id varchar(32)6 )7 as8 begin transaction9 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. 測(cè)試根據(jù)指定條件查詢(xún)數(shù)據(jù)(含輸入?yún)?shù))----------------------------------------");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("沒(méi)有更多數(shù)據(jù)進(jìn)行處理");}}4. 帶輸出參數(shù)的存儲(chǔ)過(guò)程的調(diào)用
1 GO2 if (exists (select * from sys.objects where name = 'GetT1Value'))3 drop proc GetT1Value4 go5 create proc GetT1Value(6 @t1 varchar(32),7 @count int output8 )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. 測(cè)試查詢(xún)含有輸入和輸出操作----------------------------------------");4 //把輸出參數(shù)單獨(dú)拿出來(lái)聲明5 SqlParameter para1 = new SqlParameter("@t2", SqlDbType.Int);6 para1.Direction = ParameterDirection.Output;7 //把輸出參數(shù)放到數(shù)組里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 //通過(guò)輸出參數(shù)在數(shù)組中的位置來(lái)獲取返回值。 14 var count = para2[1].Value; 15 16 Console.WriteLine($"數(shù)量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:這種調(diào)用方式,需要先聲明一下輸出類(lèi)型,然后把輸出參數(shù)放到SqlParameter這個(gè)數(shù)組里,執(zhí)行完后,通過(guò)數(shù)值下標(biāo).Value來(lái)獲取這個(gè)返回值。(和DBFirst模式下調(diào)用有所不同)
?
三. DBFirst模式快捷調(diào)用存儲(chǔ)過(guò)程
? 前面介紹的調(diào)用存儲(chǔ)過(guò)程的方法是通用模式,無(wú)論EF的哪種模式都可以使用,這里將介紹DBFirst模式的快捷調(diào)用,原理即創(chuàng)建的時(shí)候?qū)⒋鎯?chǔ)過(guò)程映射進(jìn)來(lái)了,所以可以直接調(diào)用。如下圖:
?
1. 不含任何參數(shù)(查詢(xún)類(lèi)存儲(chǔ)過(guò)程)
1 -- 1.無(wú)參存儲(chǔ)過(guò)程(查詢(xún))2 if (exists (select * from sys.objects where name = 'GetAll'))3 drop proc GetAll4 go5 create proc GetAll6 as7 select * from DBTestOne;8 9 -- 調(diào)用 10 exec GetAll; 1 private static void DBNewMethod(EFDB3Entities db) 2 { 3 Console.WriteLine("---------------------------------1. 測(cè)試查詢(xún)所有數(shù)據(jù)(不含輸入?yún)?shù))----------------------------------------"); 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. 含多個(gè)輸入?yún)?shù)(查詢(xún)類(lèi)存儲(chǔ)過(guò)程)
1 --2. 有參數(shù)的存儲(chǔ)過(guò)程(查詢(xún))2 if (exists (select * from sys.objects where name = 'GetALLBy'))3 drop proc GetALLBy4 go5 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. 測(cè)試根據(jù)指定條件查詢(xún)數(shù)據(jù)(含輸入?yún)?shù))----------------------------------------"); 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. 增刪改存儲(chǔ)過(guò)程(含1個(gè)輸入?yún)?shù))
1 --3. 增刪改的一組過(guò)程2 if (exists (select * from sys.objects where name = 'DoSome'))3 drop proc DoSome4 go 5 create proc DoSome(6 @id varchar(32)7 )8 as9 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. 測(cè)試根據(jù)指定條件查詢(xún)數(shù)據(jù)(含輸入?yún)?shù))----------------------------------------");4 int n = db.DoSome("33");5 if (n > 0)6 {7 Console.WriteLine("操作成功");8 }9 else 10 { 11 Console.WriteLine("沒(méi)有更多數(shù)據(jù)進(jìn)行處理"); 12 } 13 14 }4. 帶有輸出參數(shù)
1 if (exists (select * from sys.objects where name = 'GetT1Value'))2 drop proc GetT1Value3 go4 create proc GetT1Value(5 @t1 varchar(32),6 @count int output7 )8 as9 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. 測(cè)試查詢(xún)含有輸入和輸出操作----------------------------------------");4 //聲明一下輸出參數(shù)5 ObjectParameter para1 = new ObjectParameter("XXX", SqlDbType.Int);6 7 var tList1 = db.GetT1Value("1", para1).ToList();8 //通過(guò).Value獲取輸出參數(shù)的值。9 var count = para1.Value; 10 11 Console.WriteLine($"數(shù)量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對(duì)象來(lái)存放輸出參數(shù),執(zhí)行完后,通過(guò).Value即可以獲取輸出參數(shù),輸出參數(shù)都是一個(gè)值,還沒(méi)遇到集合的(PS:歡迎補(bǔ)充)。
?
總結(jié)
以上是生活随笔為你收集整理的第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 为何人类在核潜艇上最多只能待90天?
- 下一篇: 曝小米13系列屏幕大升级:有望首发三星E