Pregunta Obtener datos del procedimiento almacenado con Entity Framework


Estoy tratando de obtener el contenido de una tabla con un procedimiento almacenado de SQL dinámico llamado desde el objeto de contexto de la base de datos (utilizando Entity Framework 6.1.1), para llenar un GridView controlar. No puedo recuperar los datos.

Aquí está el procedimiento almacenado. Es para una demostración de estudiante sobre la inyección de SQL en procedimientos almacenados, por lo que LO SÉ esto es inyectable y está bien.

ALTER PROCEDURE dbo.SearchProducts
  @SearchTerm VARCHAR(max)
AS
BEGIN
  DECLARE @query VARCHAR(max)
  SET @query = 'SELECT * FROM dbo.Products WHERE Name LIKE ''%' + @SearchTerm + '%'''
  EXEC(@query)
END

El código C # detrás de lo que luego uso para ejecutar el procedimiento almacenado es:

var db = new MyEntities();
var TEST_SEARCH_TERM = "product";
var result = db.SearchProducts(TEST_SEARCH_TERM);

MyGridView.DataSource = result;
MyGridView.DataBind();

Cuando se ejecuta, en el explorador de base de datos en Visual Studio, el procedimiento almacenado funciona bien. Pero cuando se ejecuta en la aplicación ASP.NET en ejecución, obtengo una excepción en DataBind() método porque result devoluciones -1 en lugar de un IEnumerable  DataSet que contiene los objetos resultantes de SELECT del procedimiento almacenado.

¿Cómo puedo recuperar los datos y poblar mi GridView?


32
2017-08-21 12:50


origen


Respuestas:


Use los siguientes pasos para resolver este problema:

  1. Necesita Importar el procedimiento almacenado como una Función. Haga clic derecho en el área del área de trabajo de su modelo de Entidad y elija Add -> Function Import.
  2. En el cuadro de diálogo Agregar importación de función, ingrese el nombre al que desea que se haga referencia en su modelo en el modelo, por ejemplo Search_Products, elija su procedimiento de la lista desplegable y elija el valor de retorno del procedimiento para ser Entities y elige Products de la lista desplegable.
  3. Luego en el código detrás:

    var db = new MyEntities();
    var TEST_SEARCH_TERM = "product";
    var result = db.Search_Products(TEST_SEARCH_TERM);//Search_Products is the name that you specified in Function Import dialog
    
    MyGridView.DataSource = result;
    MyGridView.DataBind();
    

La razón por la que obtienes -1 para el resultado es que Entity Framework no puede admitir valores de devolución de procedimientos almacenados de fábrica. Creo que la compatibilidad con los valores de retorno de procedimientos almacenados depende de la versión del marco de Entity. Además, Entity Framework no tiene un soporte rico de procedimientos almacenados porque es un ORM, no un reemplazo de SQL.


29
2017-09-02 17:04



Me he encontrado con esto anteriormente con procedimientos almacenados usando SQL dinámico. He tenido éxito usando tipos complejos si agrego la línea 'SET FMTONLY OFF'; (ver https://msdn.microsoft.com/en-us/library/ms173839.aspx) a la parte superior de mi procedimiento almacenado antes de agregarlo al modelo EF. Una vez que tenga la configuración de su modelo con su tipo complejo, asegúrese de eliminar esta línea.

Ejemplo:

ALTER PROCEDURE dbo.SearchProducts
  @SearchTerm VARCHAR(max)
AS
BEGIN
  SET FMTONLY OFF;
  DECLARE @query VARCHAR(max)
  SET @query = 'SELECT * FROM dbo.Products WHERE Name LIKE ''%' + @SearchTerm + '%'''
  EXEC(@query)
END

3
2017-09-03 20:32



Verifique que su EDMX tenga un tipo de devolución: Vaya a Importaciones de funciones -> BuscarProductos, y haga doble clic en él.

Para utilizar un tipo de devolución compleja, Entity Framework requerirá que defina explícitamente los nombres de columna en su procedimiento almacenado en lugar de usar *.

Una vez que su procedimiento almacenado se modifique para definir los nombres de columna, puede actualizar su modelo en el proyecto. (Tenga en cuenta que realizar una caída completa del SP y luego volver a agregarlo a su edmx puede ser la mejor ruta).

EDITAR

Tal vez puedas modificar tu SP de la siguiente manera:

ALTER PROCEDURE dbo.SearchProducts
  @SearchTerm VARCHAR(max)
AS
BEGIN
  SELECT * FROM dbo.Products WHERE Name LIKE '%' + @SearchTerm + '%'
END

0
2017-08-21 14:36



Parece que resolvió su problema, hay documentación oficial de Microsoft disponible en los siguientes enlaces:

Cómo importar un procedimiento almacenado en su modelo de datos de entidad: https://msdn.microsoft.com/en-us/library/vstudio/bb896231(v=vs.100).aspx

Tipos complejos en el diseñador de EF: https://msdn.microsoft.com/en-gb/data/jj680147.aspx

Asegúrese de estar trabajando con la última versión de .net y mantenga su modelo actualizado cuando realice cambios en su base de datos.


0
2017-09-08 13:43