c# - visual - retornar valor stored procedure sql server




El procedimiento almacenado devuelve int en lugar del conjunto de resultados (10)

Tengo un procedimiento almacenado que contiene selección dinámica. Algo como esto:

ALTER PROCEDURE [dbo].[usp_GetTestRecords] 
    --@p1 int = 0, 
    --@p2 int = 0
    @groupId nvarchar(10) = 0
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @query  NVARCHAR(max)

    SET @query = 'SELECT * FROM CUSTOMERS WHERE Id = ' + @groupId
    /* This actually contains a dynamic pivot select statement */

    EXECUTE(@query);
END

En SSMS el procedimiento almacenado funciona bien y muestra el conjunto de resultados.

En C # usando Entity Framework, ¿muestra que se devuelve un int lugar de IEnumerable ?

private void LoadTestRecords()
{
    TestRecordsDBEntities dataContext = new TestRecordsDBEntities();
    string id = ddlGroupId.SelectedValue;

    List<TestRecord> list = dataContext.usp_GetTestRecords(id); //This part doesn't work returns int
    GridView1.DataSource = list;
}

Función generada para usp_GetTestRecords

public virtual int usp_GetTestRecords(string groupId)
{
    var groupIdParameter = groupId != null ?
        new ObjectParameter("groupId", groupId) :
        new ObjectParameter("groupId", typeof(string));

    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("usp_GetTestRecords", groupIdParameter);
}

Bueno, tuve este problema también, pero después de horas de búsqueda en línea, ninguno de los métodos anteriores me ayudó. Finalmente, llegué a saber que ocurrirá si el procedimiento de su tienda obtiene algunos parámetros como nulos y genera un error en la ejecución de la consulta. Entity Framework generará un método para el procedimiento de almacenamiento al definir el modelo de entidad complejo. Debido a ese valor nulo, su procedimiento de almacenamiento volverá e int.

Verifique el procedimiento de su tienda, ya sea proporcionando un conjunto de resultados vacío con valores nulos. Se solucionará su problema. Ojalá.


Cuando generó su clase de modelo para su procedimiento almacenado, eligió el resultado de retorno escalar por error. debe eliminar su procedimiento almacenado de su modelo de entidad y luego volver a agregar el procedimiento almacenado. En el cuadro de diálogo para el procedimiento almacenado, puede elegir el tipo de retorno que espera. No solo edite el código generado ... esto puede funcionar ahora, pero el código generado puede ser reemplazado si realiza otros cambios en su modelo.


Entity Framework devolverá automáticamente un valor escalar si su procedimiento almacenado no tiene una clave principal en su conjunto de resultados. Por lo tanto, tendría que incluir una columna de clave principal en su declaración de selección, o crear una tabla temporal con una clave principal para que Entity Framework devuelva un conjunto de resultados para su procedimiento almacenado.


Entity Framework no puede decir qué está devolviendo su procedimiento almacenado. He tenido éxito al crear una variable de tabla que refleja los datos de su declaración SELECT. Simplemente insértelo en la variable de la tabla y luego haga una selección de esa variable de tabla. EF debería recogerlo.


He reflexionado un poco sobre esto y creo que tengo una respuesta mejor / más simple

Si tiene un complejo almacenado que le da cierta dificultad al marco de la entidad (para las versiones actuales del Entity Framework que utilizan la etiqueta FMTONLY para adquirir un esquema)

Considere hacer lo siguiente al comienzo de su procedimiento almacenado.

--where [columnlist] matches the schema you want EF to pick up for your stored procedure

if 1=0
begin
    select 
       [columnlist]
    from [table list and joins]
    where 1=0
end

Si está bien al cargar su conjunto de resultados en una variable de tabla, puede hacer lo siguiente para ayudar a mantener su esquema sincronizado.

declare @tablevar as table
(
    blah int
    ,moreblah varchar(20)
)

if 1=0
begin
    select * from @tablevar
end

...
-- load data into @tablevar
select * from @tablevar

La mejor solución que encontré es hacer un poco de trampa.

En el procedimiento de la tienda, comente todo, ponga una primera línea con un select [foo]='', [bar]='' etc ... Ahora actualice el modelo, vaya a la función asignada, seleccione el tipo complejo y haga clic en Get Column Information y luego Create Complex Type .

Ahora comente la selección falsa y anule el comentario del cuerpo del procedimiento de la tienda real.


Sé que este es un hilo viejo, pero en caso de que alguien tenga los mismos problemas, les diré mis problemas.

Como ayuda para encontrar el problema, ejecute el generador de perfiles SQL cuando agregue su proceso almacenado. Luego puede ver qué marco de la entidad está pasando como parámetros para generar su conjunto de resultados. Me imagino que casi siempre pasará valores de parámetros nulos. Si está generando sql sobre la marcha mediante la concatenación de valores de cadena y valores de parámetros y algunos son nulos, el sql se interrumpirá y no obtendrá un conjunto de devolución.

No he necesitado generar tablas temporales ni nada solo un comando exec.

Espero eso ayude


Si necesita hacer esto, entonces es mejor que haga una parte del texto dbcontext y cree la función C # que utilizará SqlQuery para devolver los datos que necesita. Las ventajas sobre algunas de las otras opciones son:

  1. No tienes que cambiar nada cuando se actualiza el modelo.
  2. No se sobrescribirá si lo hace directamente en la clase generada (alguien mencionado arriba menciona esto como si fuera una opción :))
  3. No tiene que agregar nada al proceso mismo que podría tener efectos secundarios ahora o más adelante

Código de ejemplo:

 public partial class myEntities
    {
       public List<MyClass> usp_GetTestRecords(int _p1, int _p2, string _groupId)
       {
          // fill out params
          SqlParameter p1 = new SqlParameter("@p1", _p1);
          ...
          obj[] parameters = new object[] { p1, p2, groupId };

          // call the proc
          return this.Database.SqlQuery<MyClass>(@"EXECUTE usp_GetTestRecords @p1, @p2, @groupId", parameters).ToList();
       }
    }

Tengo el mismo problema, y ​​encontré solución here

  1. Muevete a tu .edmx
  2. En Model Browser Window / Function Imports encuentre su procedimiento y luego haga doble clic en él
  3. Cambie el tipo de retorno que desee
  4. Guarde .edmx y vuelva a verificar el tipo de retorno.

Debe ser lo que necesitas ahora.


Tuve el mismo problema, cambié el nombre de los campos de retorno por la palabra clave 'AS' y resolví mi problema. Una razón para este problema es nombrar nombres de columnas con palabras clave reservadas de SQL Server.

El ejemplo es barbechos:

ALTER PROCEDURE [dbo].[usp_GetProducts]

AS
BEGIN

 SET NOCOUNT ON;

 SELECT 
      , p.Id
      , p.Title
      , p.Description AS 'Description'

    FROM dbo.Products AS p
END




entity-framework