entity-framework stored-procedures temp-tables

entity framework - EF no puede inferir el esquema de devolución desde el Procedimiento almacenado seleccionando desde una tabla#temp



entity-framework stored-procedures (3)

Supongamos lo siguiente:

CREATE PROCEDURE [MySPROC] AS BEGIN CREATE TABLE #tempSubset( [MyPrimaryKey] [bigint] NOT NULL, [OtherColumn] [int] NOT NULL) INSERT INTO #tempSubset (MyPrimaryKey, OtherColumn) SELECT SomePrimaryKey, SomeColumn FROM SomeHugeTable WHERE LimitingCondition = true SELECT MyPrimaryKey, OtherColumn FROM #tempSubset WHERE SomeExpensiveCondition = true END

Cuando genero una función importar o asignar un tipo de devolución, EF no genera un tipo complejo o me dice:

El procedimiento o función almacenada seleccionada no devuelve columnas

¿Cómo superar esto?

Otras respuestas sugieren el uso de variables de tabla (que no van a hacer esto por motivos de rendimiento) simulando el esquema de retorno y comentando el procedimiento almacenado real , otras sugieren hacer lo mismo con vistas ... pero debe haber una forma de hacerlo sin tener que agregar ¿Sobrecarga innecesaria o requiriendo que rompa un procedimiento almacenado para actualizar el modelo?


Agregando esto a la parte superior de la definición del procedimiento almacenado:

SET FMTONLY OFF permitió que el modelo infiera el esquema de la tabla temporal sin problema. Como beneficio adicional, no requiere mantenimiento adicional para un contrato.

Ejemplo:

SET FMTONLY OFF CREATE TABLE #tempTable ( ... ) ... SELECT * FROM #tempTable


Solución 1 Utilice una variable de tabla en lugar de una tabla temporal.

Solución 2 Use el ajuste FMTONLY desactivado; Comando SQL en el procedimiento y obtendrá la información de la columna para crear un nuevo tipo complejo.

Solución 3 Esta no es una buena manera, pero es una manera muy fácil. Simplemente agregue una instrucción de selección con datos ficticios y no se ejecutará porque 1 = 0.

puedes verificar los detalles en este enlace


CREATE PROCEDURE [MySPROC] AS BEGIN --supplying a data contract IF 1 = 2 BEGIN SELECT cast(null as bigint) as MyPrimaryKey, cast(null as int) as OtherColumn WHERE 1 = 2 END CREATE TABLE #tempSubset( [MyPrimaryKey] [bigint] NOT NULL, [OtherColumn] [int] NOT NULL) INSERT INTO #tempSubset (MyPrimaryKey, OtherColumn) SELECT SomePrimaryKey, SomeColumn FROM SomeHugeTable WHERE LimitingCondition = true SELECT MyPrimaryKey, OtherColumn FROM #tempSubset WHERE SomeExpensiveCondition = true END

El suministro de un contrato de datos falsos para el conjunto de resultados es la forma más fácil, limpia y rápida de solucionar el problema. Este mismo problema existe en los controles de fuente de datos en SSIS también. .NET leerá el conjunto de resultados de la sección "contrato" inalcanzable de la consulta y proporcionará los metadatos para el tipo complejo. Sin impacto en el rendimiento y sin necesidad de comentar el SQL que realiza el trabajo real.