第七节:EF Core调用SQL语句和存储过程(2.x和3.x写法)

一. 查询类

  EFCore2.x中用 FromSql 方法,EFCore3.x中用 FromSqlRaw 方法,二者使用起来基本一致。

1.说明

  A. SQL查询必须返回实体的所有属性字段。

  B. 结果集中的列名必须与属性映射到的列名相匹配。

  C. SQL查询不能包含关联数据

  D. 除Select以为的其它SQL语句无法运行。

2.调用SQL语句的几种情况

  A. 基本的原生SQL查询

  B. 利用$内插语法进行传递

  C. 原生SQL与linq语法相结合

  D. 利用SqlParameter进行参数化查询

代码分享:(2.x版本的写法)

 1 {
 2                 using (EFDB01Context db = new EFDB01Context())
 3                 {
 4                     //1.基本的原生SQL查询
 5                     var userList1 = db.Set<T_UserInfor>().FromSql("select * from T_UserInfor where id!='123'").ToList();
 6 
 7                     //2.利用$内插语法进行传递
 8                     var myId = "2fc343069e0a4a559b62b08d5999dbcd";
 9                     var userList2 = db.Set<T_UserInfor>().FromSql($"select * from T_UserInfor where id= {myId}").ToList();
10 
11                     //3.原生SQL与linq语法相结合
12                     var userList3 = db.Set<T_UserInfor>().FromSql($"select * from T_UserInfor")
13                         .Where(u => u.id == "2fc343069e0a4a559b62b08d5999dbcd")
14                         .ToList();
15                     var userList4 = db.Set<T_UserInfor>().FromSql($"select * from T_UserInfor")
16                         .Where(u => u.id != "1111")
17                         .OrderBy(u => u.addTime)
18                         .ToList();
19 
20                     //4.利用SqlParameter进行参数化查询
21                     SqlParameter[] paras ={
22                                              new SqlParameter("@id","2fc343069e0a4a559b62b08d5999dbcd"),
23                                              new SqlParameter("@userName","ypf"),
24                                         };
25                     var userList5 = db.Set<T_UserInfor>().FromSql("select * from T_UserInfor where id=@id and userName=@userName", paras).ToList();
26                 }
27 }

3.调用存储过程的几种情况

  可以利用SqlParameter传递参数,防止sql注入。

  A.不含任何参数

  B.含多个输入参数

  C.含输入参数和输出参数

 用到的表结构:

 对应的生成存储过程的代码:

 1 USE [EFDB01]
 2 
 3 --事先准备:插入两条数据
 4 select * from T_UserInfor
 5 truncate table T_UserInfor
 6 insert into T_UserInfor values('01','ypf','',12,'2019-08-08')
 7 insert into T_UserInfor values('02','ypf2','',30,'2019-09-08')
 8 
 9 -- 1. 不含任何参数存储过程
10 if (exists (select * from sys.objects where name = 'GetAll'))
11     drop proc GetAll
12 go
13     create proc GetAll
14 as
15     select * from T_UserInfor;
16 
17 -- 调用
18 exec GetAll;
19 
20 
21 --2. 含多个输入参数的存储过程
22 if (exists (select * from sys.objects where name = 'GetALLBy'))
23     drop proc GetALLBy
24 go
25     create proc GetALLBy(
26         @id varchar(32),
27         @userName varchar(20)
28     )
29 as
30     select * from T_UserInfor where id=@id and userName=@userName;
31 
32 exec GetALLBy @id='01',@userName='ypf';
33 
34 --3. 含输出参数的存储过程
35  if (exists (select * from sys.objects where name = 'GetSpecial'))
36     drop proc GetSpecial
37 go
38     create proc GetSpecial(
39         @userName varchar(32),
40         @count int output
41     )
42 as
43     select @count=count(*) from T_UserInfor;
44     select * from T_UserInfor where userName= @userName;
45 
46 go
47 declare @myCount int;
48 exec GetSpecial 'ypf',@myCount output;
49 select @myCount as myCount;

对应EF调用的代码:(2.x的写法)

 1             {
 2                 using (EFDB01Context db = new EFDB01Context())
 3                 {
 4                     //1. 不含任何参数存储过程
 5                     var data1 = db.Set<T_UserInfor>().FromSql("GetAll").ToList();
 6 
 7                     //2. 含多个输入参数的存储过程
 8                     SqlParameter[] para ={
 9                                            new SqlParameter("@id","01"),
10                                            new SqlParameter("@userName","ypf")
11                                   };
12                     var data2 = db.Set<T_UserInfor>().FromSql("GetALLBy @id,@userName", para).ToList();
13 
14                     //3. 带输出参数的存储过程
15                     //把输出参数单独拿出来声明
16                     SqlParameter myCount = new SqlParameter("@count", SqlDbType.Int);
17                     myCount.Direction = ParameterDirection.Output;
18                     //把输出参数放到数组里
19                     SqlParameter[] para2 ={
20                                            new SqlParameter("@userName","ypf"),
21                                            myCount
22                                      };
23                     var data3 = db.Set<T_UserInfor>().FromSql("exec GetSpecial @userName,@count out", para2).ToList();
24                     //通过输出参数在数组中的位置来获取返回值。
25                     var count = para2[1].Value;
26 
27                 }
28             }

 

二. 其它类

  EFCore2.x中用 ExecuteSqlCommand 方法,EFCore3.x中用 ExecuteSqlRaw 方法,二者使用起来基本一致。

1.说明

  主要用于调用除了查询外其它的SQL语句。

2.调用SQL语句的情况

  A. 基本的原生SQL查询

  B. 利用$内插语法进行传递

  C. 利用SqlParameter进行参数化查询

代码分享:(2.x的写法)

 1             {
 2                 using (EFDB01Context db = new EFDB01Context())
 3                 {
 4 
 5                     //1.增加
 6                     int result1 = db.Database.ExecuteSqlCommand("insert into T_UserInfor values('01','test1','男',21,'2019-09-09')");
 7 
 8                     //2. 修改
 9                     SqlParameter[] paras ={
10                                                      new SqlParameter("@id","01"),
11                                                      new SqlParameter("@userSex","未知"),
12                                                 };
13                     int result2 = db.Database.ExecuteSqlCommand("update T_UserInfor set userSex=@userSex where id=@id", paras);
14 
15                     //3. 删除
16                     var myId = "01";
17                     int result3 = db.Database.ExecuteSqlCommand($"delete from T_UserInfor where id={myId}");
18 
19                     //4. 其它指令
20                     int result4 = db.Database.ExecuteSqlCommand("truncate table T_UserInfor");
21                 }
22             }

3.调用存储过程的情况

 存储过程代码

--4. 非查询类的存储过程
if (exists (select * from sys.objects where name = 'DoSome'))
    drop proc DoSome
go 
    create proc DoSome(
        @id varchar(32)
    )
as
    begin transaction
 begin try
        insert into T_UserInfor values(@id,'ypf','',12,'2019-08-08');
        delete from T_UserInfor where id='02'
    commit transaction
 end try
 begin catch
    rollback transaction
 end catch

 exec DoSome '03'

EF的调用代码 (2.x的写法)

 1             {
 2                 using (EFDB01Context db = new EFDB01Context())
 3                 {
 4                     SqlParameter[] para ={
 5                                            new SqlParameter("@id",Guid.NewGuid().ToString("N")),
 6                                      };
 7                     int n = db.Database.ExecuteSqlCommand("DoSome @id", para);
 8                     if (n > 0)
 9                     {
10                         Console.WriteLine("操作成功");
11                     }
12                     else
13                     {
14                         Console.WriteLine("没有更多数据进行处理");
15                     }
16                 }
17             }

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
posted @ 2019-09-04 14:56  Yaopengfei  阅读(2083)  评论(2编辑  收藏  举报