zoukankan      html  css  js  c++  java
  • 第四节: 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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
     
  • 相关阅读:
    信息和熵
    【算法】欧几里得算法与青蛙约会oj
    【算法】并查集模板与练习
    Kaggle-房价预测
    【pytorch】pytorch-backward()的理解
    【pytorch】pytorch-LSTM
    【计算机网络】数据链路层总结
    【Code】numpy、pytorch实现全连接神经网络
    【MT】牛津的MT教程
    【计算机网络】物理层基础知识
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/7699530.html
Copyright © 2011-2022 走看看