Estoy codificando una aplicación web con ASP.NET MVC usando Entity Framework.

Llamo al procedimiento así en C #:

var result = context.EditTechInfo(user.id, user.telephone, user.email);

Donde context es la instancia de Entity Framework.

Tengo un procedimiento que siempre devuelve -1, pero ejecuta el UPDATE que se supone que debe hacer. Intenté devolver mi valor usando SELECT en lugar de RETURN pero fue en vano.

Aquí está el procedimiento:

ALTER PROCEDURE EditTechInfo
    (@tech INT,
     @telephone CHAR(10),
     @email VARCHAR(64))
AS
BEGIN
    SET NOCOUNT ON
    DECLARE @result  INT = 0

    IF EXISTS (SELECT * FROM Techs WHERE id = @tech AND statut = 1)
    BEGIN
        UPDATE Techs
        SET telephone = @telephone, email = @email
        WHERE id = @tech

        SET @result = 1
    END
    --ELSE
    --BEGIN
        --SET @result = -1
    --END

    SELECT @result
END

Incluso si se comenta la parte donde -1 podría ser el valor devuelto ...

Sé que si un procedimiento devuelve -1, significa que hubo un error, pero no puedo imaginar dónde ni por qué ...

----EDITAR-------

Como se preguntó en el comentario, esto es lo que EF generó:

public virtual int EditTechInfo(Nullable<int> tech, string telephone, string email)
        {
            var techParameter = tech.HasValue ?
                new ObjectParameter("tech", tech) :
                new ObjectParameter("tech", typeof(int));

            var telephoneParameter = telephone != null ?
                new ObjectParameter("telephone", telephone) :
                new ObjectParameter("telephone", typeof(string));

            var emailParameter = email != null ?
                new ObjectParameter("email", email) :
                new ObjectParameter("email", typeof(string));

            return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("EditTechInfo", techParameter, telephoneParameter, emailParameter);
        }
2
Chax 20 sep. 2016 a las 05:08

3 respuestas

La mejor respuesta

Tetsuya Yamamoto sugirió que use el parámetro OUTPUT. He leído un poco más sobre el asunto. Decidí utilizar este enfoque y funcionó.

Agregué un nuevo parámetro, observe el parámetro OUTPUT

Aquí está el PROCEDURE modificado:

CREATE PROCEDURE EditTechInfo
(
    @tech           INT,
    @telephone      CHAR(10),
    @email          VARCHAR(64),
    @result         INT OUTPUT --- this is new
)
AS
BEGIN
    SET NOCOUNT ON
    SET @result = 0;

    IF EXISTS (SELECT * FROM Techs WHERE id = @tech AND statut = 1)
    BEGIN
        UPDATE Techs
            SET telephone = @telephone, email = @email
        WHERE id = @tech

        SET @result = 1
    END
    ELSE
    BEGIN
        SET @result = -1
    END

    RETURN @result -- I don't know if i have to actually return it since it is an output param
END

Así es como se llama dentro de c#: (tenga en cuenta que es un código demasiado simplificado)

El gran complemento aquí es que cambié el tipo de variable result a ObjectParameter. Después de eso, tuve que recuperar el Value de mi resultado. Lo convertí en un int; de lo contrario, es un Object simple.

public int GetEditTechInfoValue(int id, string telephone, string email)
        {
            var result = new ObjectParameter("result", 0);
            var type = result.ParameterType;

            // This is an instance of my EntityFramework entities...you get the point
            context.EditTechInfo(id, telephone, email, result);

            return (int)result.Value;
        }
1
Community 23 may. 2017 a las 11:53

Están obteniendo -1 debido a SET NOCOUNT ON. Elimínelo o especifique SET NOCOUNT OFF para obtener el recuento de filas afectadas por el proceso.

Tenga en cuenta que el uso generalizado de SET NOCOUNT ON tiene sus raíces en el ADODB clásico, donde los recuentos de filas (en realidad, mensajes DONE_IN_PROC TDS) confundían a las aplicaciones que no los esperaban. Esto no es un problema con SqlClient porque la API funciona mejor desde una perspectiva de desarrollo.

-1
Dan Guzman 20 sep. 2016 a las 02:24

Prueba este código. Funcionará en EF 6+

String spQuery = String.Format("EditTechInfo {0},'{1}','{2}'", 0, "telephone  ", "email");
int result = context.Database.SqlQuery<int>(spQuery).FirstOrDefault();
1
syed mhamudul hasan akash 20 sep. 2016 a las 03:27