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.