Existe-t-il un moyen d'appeler une procédure stockée avec Dapper?


205

Je suis très impressionné par les résultats de Dapper Micro ORM pour stackoverflow.com. Je l'envisage pour mon nouveau projet et mais je suis préoccupé par le fait que mon projet nécessite parfois d'avoir une procédure stockée et j'ai beaucoup recherché sur le Web, mais je n'ai rien trouvé avec la procédure stockée. Existe-t-il un moyen de faire fonctionner Dapper avec une procédure stockée?

Veuillez me faire savoir si c'est possible sinon je dois le prolonger à ma façon.


Réponses:


356

Dans le cas simple, vous pouvez faire:

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

Si vous voulez quelque chose de plus sophistiqué, vous pouvez faire:

 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"); 

De plus, vous pouvez utiliser exec dans un lot, mais c'est plus maladroit.


1
Le paramètre avec la direction de ReturnValue doit être défini en premier, non?
Endy Tjahjono

3
@Sam Saffron Quelle est la différence entre .Output et .ReturnVlaue?
Intemporel

Sam, cela permet-il des jeux de résultats des SPROC?
Brad

2
J'ai obtenu un scénario dans lequel je prendrai le jeu de résultats de la requête et la valeur du paramètre de sortie dans une procédure. Si j'utilise cnn.Query<MyType>comment puis-je obtenir la valeur du paramètre de sortie du proc?
Murali Murugesan

La deuxième solution (fantaisie) est également utile lorsque vous devez passer une valeur nulle pour un ou plusieurs paramètres de procédure stockée.
Ricardo Sanchez

13

Je pense que la réponse dépend des fonctionnalités des procédures stockées que vous devez utiliser.

Les procédures stockées renvoyant un jeu de résultats peuvent être exécutées à l'aide de Query; les procédures stockées qui ne renvoient pas de jeu de résultats peuvent être exécutées en utilisant Execute- dans les deux cas (en utilisant EXEC <procname>) comme la commande SQL (plus les paramètres d'entrée si nécessaire). Voir la documentation pour plus de détails.

Depuis la révision 2d128ccdc9a2, il ne semble pas y avoir de support natif pour les OUTPUTparamètres; vous pouvez ajouter ceci, ou bien construire un plus complexeQuery commande qui déclare les variables TSQL, exécute les OUTPUTparamètres de collecte SP dans les variables locales et les renvoie finalement dans un jeu de résultats:

DECLARE @output int

EXEC <some stored proc> @i = @output OUTPUT

SELECT @output AS output1

17
vient d'ajouter la prise en charge des paramètres de sortie maintenant, voir mon dernier enregistrement
Sam Saffron

6
@Sam - c'est ce que j'appelle le service!
Ed Harper

6

Voici le code pour obtenir le retour de valeur de la procédure Store

Procédure stockée:

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 

Code:

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");

2

Idem d'en haut, un peu plus détaillé

Utilisation de .Net Core

Manette

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; }            
    }
}

Procédure stockée (relation parent-enfant)

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

Références en cas

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 Microsoft.EntityFrameworkCore;
using Dapper;
using System.Data;
using System.Data.SqlClient;

Pourquoi utiliser Microsoft.EntityFrameworkCore? Vous utilisez uniquement Dapper dans DAL ?
PreguntonCojoneroCabrón

@ PreguntonCojoneroCabrón Pas nécessaire, je viens de tout coller
Arun Prasad ES

Exemples de lignes pour EventCategory?
Kiquenet

@ArunPrasadES au point PreguntonCojoneroCabrón, veuillez nettoyer et supprimer le code inutile car cela déroute les gens qui essaient de résoudre un problème. Il existe des fonctionnalités dans Visual Studio et Resharper qui effectuent ce nettoyage des utilisations pour vous.
Cubicle.Jockey

1

Avec retour multiple et paramètres multiples

string ConnectionString = CommonFunctions.GetConnectionString();
using (IDbConnection conn = new SqlConnection(ConnectionString))
{
    IEnumerable<dynamic> results = conn.Query(sql: "ProductSearch", 
        param: new { CategoryID = 1, SubCategoryID="", PageNumber=1 }, 
        commandType: CommandType.StoredProcedure);.  // single result

    var reader = conn.QueryMultiple("ProductSearch", 
        param: new { CategoryID = 1, SubCategoryID = "", PageNumber = 1 }, 
        commandType: CommandType.StoredProcedure); // multiple result

    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;
}

Échantillon ProductSearch ? renvoie 2 curseurs?
PreguntonCojoneroCabrón

0
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();
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.