C'è un modo per chiamare una procedura memorizzata con Dapper?


205

Sono rimasto molto colpito dai risultati di Dapper Micro ORM per stackoverflow.com. Lo sto prendendo in considerazione per il mio nuovo progetto, ma ho una preoccupazione in merito al fatto che alcune volte il mio progetto richiede di avere una Stored Procedure e ho cercato molto sul web ma non ho trovato nulla con la stored procedure. Quindi c'è un modo per far funzionare Dapper con una procedura memorizzata?

Per favore fatemi sapere se è possibile, altrimenti devo estenderlo a modo mio.


Guarda i miei dettagli risposta qui stackoverflow.com/questions/5957774/...
Majedur Rahaman

Risposte:


356

Nel caso semplice puoi fare:

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

Se vuoi qualcosa di più elegante, puoi fare:

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

Inoltre puoi usare exec in un batch, ma è più goffo.


1
Il parametro con la direzione di ReturnValue deve essere definito per primo, giusto?
Endy Tjahjono,

3
@Sam Saffron Qual è la differenza tra .Output e .ReturnVlaue?
Senza tempo,

Sam, questo consente set di risultati dagli SPROC?
Brad,

2
Ho ottenuto uno scenario in cui prenderò il set di risultati della query e il valore del parametro Output in una procedura. Se utilizzo cnn.Query<MyType>come posso ottenere il valore del parametro Output del proc?
Murali Murugesan,

La seconda soluzione (elaborata) è utile anche quando è necessario passare un valore null per uno o più parametri della procedura memorizzata.
Ricardo Sanchez,

13

Penso che la risposta dipenda dalle caratteristiche delle procedure memorizzate che è necessario utilizzare.

Le procedure memorizzate che restituiscono un set di risultati possono essere eseguite utilizzando Query; le procedure memorizzate che non restituiscono un set di risultati possono essere eseguite usando Execute- in entrambi i casi (usando EXEC <procname>) come comando SQL (più i parametri di input se necessario). Vedi la documentazione per maggiori dettagli.

A partire dalla revisione 2d128ccdc9a2 non sembra esserci supporto nativo per i OUTPUTparametri; potresti aggiungere questo, o in alternativa costruire un Querycomando più complesso che ha dichiarato le variabili TSQL, eseguito i OUTPUTparametri di raccolta SP nelle variabili locali e infine restituiti in un set di risultati:

DECLARE @output int

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

SELECT @output AS output1

17
ho appena aggiunto il supporto per i parametri di output ora, vedi il mio ultimo check-in
Sam Saffron

6
@ Sam - questo è ciò che chiamo servizio!
Ed Harper,

6

Ecco il codice per ottenere il ritorno di valore dalla procedura Store

Procedura memorizzata:

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 

Codice:

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

Lo stesso da sopra, un po 'più dettagliato

Utilizzando .Net Core

controllore

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

Stored procedure (relazione figlio principale)

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

Riferimenti nel caso

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;

Perché usare Microsoft.EntityFrameworkCore? Usi solo Dapper in DAL ?
PreguntonCojoneroCabrón,

@ PreguntonCojoneroCabrón Non necessario, ho appena incollato tutto
Arun Prasad ES

Righe di esempio per EventCategory?
Kiquenet,

@ArunPrasadES al punto PreguntonCojoneroCabrón, si prega di ripulire e rimuovere il codice non necessario in quanto confonde le persone che cercano di risolvere un problema. Esistono funzionalità di Visual Studio e Resharper che consentono di utilizzare la pulizia per te.
Cubicle.Jockey

1

Con ritorno multiplo e multiparametro

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

Esempio di ProductSearch ? restituisce 2 cursori?
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();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.