web-dev-qa-db-fra.com

Exécution d'une procédure stockée SQL avec un paramètre de sortie depuis Entity Framework

En utilisant EF, j'essaie d'exécuter une procédure stockée qui renvoie une valeur de chaîne unique, c'est-à-dire le statut d'un travail d'agent SQL.

La procédure stockée est déclarée comme

CREATE PROCEDURE [dbo].[up_GetJobStatus](@JobStatus NVARCHAR(30) OUTPUT)
AS

-- some code omitted for brevity

SELECT @JobStatus = (
SELECT  
    CASE job_state 
    WHEN 1 THEN 'Executing'
    WHEN 2 THEN 'Waiting for thread'
    WHEN 3 THEN 'Between retries'
    WHEN 4 THEN 'Idle'
    WHEN 5 THEN 'Suspended'
    WHEN 6 THEN '<unknown>'
    WHEN 7 THEN 'Performing completion actions'
END
FROM @xp_results results 
INNER JOIN msdb.dbo.sysjobs sj
ON results.job_id = sj.job_id
WHERE sj.job_id = @job_id)

RETURN

J'ai vérifié que la procédure stockée fonctionne correctement car je peux l'exécuter dans la fenêtre de requête et elle retourne

    @JobStatus
  ------------
  1|Idle

Cependant lors de l'exécution avec EF, la valeur param est NULL

var param = new SqlParameter
{
    ParameterName = "@JobStatus",
    DbType = DbType.String,
    Size = 30,
    Direction = System.Data.ParameterDirection.Output
};

var result = this.etlContext.Database.SqlQuery<string>("EXEC dbo.up_GetJobStatus @JobStatus OUTPUT", param);

J'ai également essayé la méthode ExecuteSqlCommand mais cela n'a pas fonctionné non plus.

Des idées?

14
empo
  1. Créer une procédure stockée dans la base de données

    CREATE PROCEDURE [dbo].myStoredProcName
        @inputParam1 VARCHAR(150),
        @inputParam2 VARCHAR(150),
        @myOutputParamBool BIT OUTPUT,
        @myOutputParamString VARCHAR(100) OUTPUT,
        @myOutputParamInt INT OUTPUT
    AS
    BEGIN
        -- sql here
    END
    
  2. Mettre à jour le modèle d'entité de la base de données pour inclure la procédure stockée comme indiqué ici

  3. Appeler la procédure stockée à partir du code C #

    System.Data.Entity.Core.Objects.ObjectParameter myOutputParamBool=new System.Data.Entity.Core.Objects.ObjectParameter("myOutputParamBool",typeof(bool));
    System.Data.Entity.Core.Objects.ObjectParameter myOutputParamString=new System.Data.Entity.Core.Objects.ObjectParameter("myOutputParamString",typeof(string));
    System.Data.Entity.Core.Objects.ObjectParameter myOutputParamInt=new System.Data.Entity.Core.Objects.ObjectParameter("myOutputParamInt",typeof(Int32));
    
    using (var context = new SandCryptEntities())
    {
        context.myStoredProcName(inputParam1, inputParam2, myOutputParamBool, myOutputParamString, myOutputParamInt);   
    }
    
    bool myBool = Convert.ToBoolean(myOutputParamBool.Value);
    string myString = Convert.ToString(myOutputParamString.Value);
    int myInt = Convert.ToInt32(myOutputParamInt.Value);
    
24
Augis

Voici une vraie réponse. Apparemment, il y a de sérieux problèmes avec les paramètres de sortie dans le cadre d'entité lorsque vous utilisez d'abord DbContext/code. Cet article a une bonne discussion et solution: http://weblogs.asp.net/dwahlin/using-entity-framework-code-first-with-stored-procedures-that-have-output-parameters =. Apparemment, il est censé être "corrigé" avec une mise à jour, mais je n'ai pas vraiment vu cela se produire.

4
sovemp

Utilisez le code suivant, cela fonctionne de mon côté.

            var param = new SqlParameter
            {
                ParameterName = "@JobStatus",
                DbType = DbType.String,
                Size = 30,
                Direction = System.Data.ParameterDirection.Output
            };

            var result = this.etlContext.Database.SqlQuery<string>("EXEC dbo.up_GetJobStatus @JobStatus=@JobStatus OUTPUT", param);
            string JobStatus = param.Value.ToString();

Le premier @JobStatus est votre paramètre ParameterName et le second @JobStatus est PROCEDURE le nom du paramètre.

0
vicky