【问题标题】:Is there a way to call a stored procedure with Dapper?有没有办法用 Dapper 调用存储过程?
【发布时间】:2023-03-27 11:39:01
【问题描述】:

Dapper Micro ORMstackoverflow.com 的结果给我留下了深刻的印象。我正在为我的新项目考虑它,但我担心有时我的项目需要存储过程并且我在网上搜索了很多但没有找到任何存储过程。那么有什么方法可以让 Dapper 使用存储过程?

如果可能,请告诉我,否则我必须以我的方式扩展它。

【问题讨论】:

    标签: .net stored-procedures orm dapper


    【解决方案1】:

    在简单的情况下你可以这样做:

    var user = cnn.Query<User>("spGetUser", new {Id = 1}, 
            commandType: CommandType.StoredProcedure).First();
    

    如果你想要更花哨的东西,你可以这样做:

     var p = new DynamicParameters();
     p.Add("@a", 11);
     p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);
     p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
    
     cnn.Execute("spMagicProc", p, commandType: CommandType.StoredProcedure); 
    
     int b = p.Get<int>("@b");
     int c = p.Get<int>("@c"); 
    

    此外,您可以批量使用 exec,但这更笨重。

    【讨论】:

    • 应该先定义ReturnValue方向的参数吧?
    • @Sam Saffron .Output 和 .ReturnVlaue 有什么区别?
    • Sam,这是否允许来自 SPROC 的结果集?
    • 我遇到了一个场景,我将在一个过程中获取查询结果集和输出参数值。如果我使用cnn.Query&lt;MyType&gt;,如何获取proc的Output参数值?
    • 第二种(奇特的)解决方案在需要为一个或多个存储过程参数传递空值时也很有帮助。
    【解决方案2】:

    我认为答案取决于您需要使用存储过程的哪些功能。

    可以使用Query 运行返回结果集的存储过程;不返回结果集的存储过程可以使用Execute 运行——在这两种情况下(使用EXEC &lt;procname&gt;)作为SQL 命令(必要时加上输入参数)。有关详细信息,请参阅documentation

    截至修订版2d128ccdc9a2 似乎没有对OUTPUT 参数的原生支持;你可以添加这个,或者构造一个更复杂的 Query 命令来声明 TSQL 变量,执行 SP,将 OUTPUT 参数收集到局部变量中,最后在结果集中返回它们:

    DECLARE @output int
    
    EXEC <some stored proc> @i = @output OUTPUT
    
    SELECT @output AS output1
    

    【讨论】:

    • 刚刚添加了对输出参数的支持,请参阅我的最新签入
    • @Sam - 这就是我所说的服务!
    【解决方案3】:

    这是从 Store 过程中获取值返回的代码

    存储过程:

    alter proc [dbo].[UserlogincheckMVC]    
    @username nvarchar(max),    
    @password nvarchar(max)
    as    
    begin    
        if exists(select Username from Adminlogin where Username =@username and Password=@password)    
            begin        
                return 1  
            end    
        else    
            begin     
                return 0  
            end    
    end 
    

    代码:

    var parameters = new DynamicParameters();
    string pass = EncrytDecry.Encrypt(objUL.Password);
    conx.Open();
    parameters.Add("@username", objUL.Username);
    parameters.Add("@password", pass);
    parameters.Add("@RESULT", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
    var RS = conx.Execute("UserlogincheckMVC", parameters, null, null, commandType: CommandType.StoredProcedure);
    int result = parameters.Get<int>("@RESULT");
    

    【讨论】:

      【解决方案4】:

      同上,更详细一点

      使用 .Net Core

      控制器

      public class TestController : Controller
      {
          private string connectionString;
        
          public IDbConnection Connection
          {
              get { return new SqlConnection(connectionString); }
          }
      
          public TestController()
          {
              connectionString = @"Data Source=OCIUZWORKSPC;Initial Catalog=SocialStoriesDB;Integrated Security=True";
          }
      
          public JsonResult GetEventCategory(string q)
          {
              using (IDbConnection dbConnection = Connection)
              {
                  var categories = dbConnection.Query<ResultTokenInput>("GetEventCategories", new { keyword = q },
          commandType: CommandType.StoredProcedure).FirstOrDefault();
      
                  return Json(categories);
              }
          }
      
          public class ResultTokenInput
          {
              public int ID { get; set; }
              public string name { get; set; }            
          }
      }
      

      存储过程(父子关系)

      create PROCEDURE GetEventCategories
      @keyword as nvarchar(100)
      AS
          BEGIN
      
          WITH CTE(Id, Name, IdHierarchy,parentId) AS
          (
            SELECT 
              e.EventCategoryID as Id, cast(e.Title as varchar(max)) as Name,
              cast(cast(e.EventCategoryID as char(5)) as varchar(max)) IdHierarchy,ParentID
            FROM 
              EventCategory e  where e.Title like '%'+@keyword+'%'
           -- WHERE 
            --  parentid = @parentid
      
            UNION ALL
      
            SELECT 
              p.EventCategoryID as Id, cast(p.Title + '>>' + c.name as varchar(max)) as Name,
              c.IdHierarchy + cast(p.EventCategoryID as char(5)),p.ParentID
            FROM 
              EventCategory p 
            JOIN  CTE c ON c.Id = p.parentid
      
              where p.Title like '%'+@keyword+'%'
          )
          SELECT 
            * 
          FROM 
            CTE
          ORDER BY 
            IdHierarchy
      

      案例参考

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Threading.Tasks;
      using Microsoft.AspNetCore.Mvc;
      using Microsoft.AspNetCore.Http;
      using SocialStoriesCore.Data;
      using Dapper;
      using System.Data;
      using System.Data.SqlClient;
      

      【讨论】:

      • 为什么使用Microsoft.EntityFrameworkCore ?仅在 DAL 中使用 Dapper
      • @PreguntonCojoneroCabrón 没必要,我只是粘贴了所有内容
      • EventCategory 的示例行?
      • @ArunPrasadES to PreguntonCojoneroCabrón 点,请清理并删除不必要的代码,因为它会混淆试图解决问题的人。 Visual Studio 和 Resharper 中有一些功能可以为您清理这些使用情况。
      • @PreguntonCojoneroCabrón 按照建议删除了Microsoft.EntityFrameworkCore
      【解决方案5】:

      多返回多参数

      string ConnectionString = CommonFunctions.GetConnectionString();
      using (IDbConnection conn = new SqlConnection(ConnectionString))
      {
          // single result
          var results = conn.Query(sql: "ProductSearch", 
              param: new { CategoryID = 1, SubCategoryID="", PageNumber=1 }, 
              commandType: CommandType.StoredProcedure);
      
          // multiple result
          var reader = conn.QueryMultiple("ProductSearch", 
              param: new { CategoryID = 1, SubCategoryID = "", PageNumber = 1 }, 
              commandType: CommandType.StoredProcedure); 
      
          var userdetails = reader.Read<dynamic>().ToList(); // instead of dynamic, you can use your objects
          var salarydetails = reader.Read<dynamic>().ToList();
      }
      
      public static string GetConnectionString()
      {
          // Put the name the Sqlconnection from WebConfig..
          return ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
      }
      

      【讨论】:

      • 产品搜索 示例?返回 2 个游标?
      【解决方案6】:
      public static IEnumerable<T> ExecuteProcedure<T>(this SqlConnection connection,
          string storedProcedure, object parameters = null,
          int commandTimeout = 180) 
          {
              try
              {
                  if (connection.State != ConnectionState.Open)
                  {
                      connection.Close();
                      connection.Open();
                  }
      
                  if (parameters != null)
                  {
                      return connection.Query<T>(storedProcedure, parameters,
                          commandType: CommandType.StoredProcedure, commandTimeout: commandTimeout);
                  }
                  else
                  {
                      return connection.Query<T>(storedProcedure,
                          commandType: CommandType.StoredProcedure, commandTimeout: commandTimeout);
                  }
              }
              catch (Exception ex)
              {
                  connection.Close();
                  throw ex;
              }
              finally
              {
                  connection.Close();
              }
      
          }
      }
      
      var data = db.Connect.ExecuteProcedure<PictureModel>("GetPagePicturesById",
          new
          {
              PageId = pageId,
              LangId = languageId,
              PictureTypeId = pictureTypeId
          }).ToList();
      

      【讨论】:

        猜你喜欢
        • 2012-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多