none
Error 3027: No hay ninguna asignación especificada para el siguiente EntitySet o AssociationSet RRS feed

  • Pregunta

  • Buenos días:

    Me está dando un error del que no encuentro nada de documentación por la red. Os lo pongo a ver si a alguno os ha dado con anterioridad, para ver cómo lo habéis solucionado.

    Error 3027: No hay ninguna asignación especificada para el siguiente EntitySet o AssociationSet

    Lo que estoy haciendo es crear una nueva entidad que se carga de un procedimiento almacenado a través de una función de importación. Hasta ahí todo bien. Si dentro del procedimiento almacenado me limito a poner (es un ejemplo) "select id, nombre from productos", la función de importación reconoce ambas columnas y todo funciona bien. Pero si creo una tabla temporal (#prods, por ejemplo), hago "insert into #prods select id, nombre from productos" y "select id, nombre from #prods" (todo eso va dentro del procedimiento almacenado), cuando en la función de importación doy a "Obtener información de columna" me dice "el procedimiento almacenado seleccionado no devuelve columnas". Y sin embargo, si lo ejecuto desde cualquier otro sitio me devuelve exactamente la misma información que haciendo directamente "select id, nombre from productos".

    Y como la función de importación no consigue recuperar la información de las columnas, no se asignan dichas columnas a las propiedades de la entidad, y consecuentemente da ese error 3027 del que no hay información por internet.

    ¿Alguno habéis conseguido usar entidades con funciones de importación que lean de procedimientos almacenados que devuelvan conjuntos de datos de tablas temporales?

    Muchas gracias


    Carlos Adrián Martínez

    viernes, 17 de febrero de 2012 10:57

Respuestas

  • Hola Carlos.

    Generalmente para estos casos en los que no se puede crear la entidad compleja, suelo parchear la consulta para obtener los datos que yo quiera (aunque lo hago cuando no dispongo de alguna BBDD asociada).

    Pero en tu caso, aunque puedes parchearlo como te he comentado antes, me ha intrigado y he analizado el proceso, el resultado es el siguiente:

    He creado un procedimiento llamado prueba (uno sencillo que crea una tabla temporal para obtener los datos:

    ALTER PROCEDURE [dbo].[Prueba] 
    AS
    BEGIN
    	-- Prevenir resultados extra
    	SET NOCOUNT ON;
    
    	-- crear tabla temporal
    	CREATE TABLE #prods (CustomerID int, FirstName nvarchar(50))
    	-- inertar tabla en la temporal
    	insert into #prods select CustomerID, FirstName from SalesLT.Customer
    	
    	
    	-- realizar la consulta sobre la tabla temporal
    	select CustomerID, FirstName from #prods
    	
    END

    Luego he intentado importar la funcion y no retorna ningun resultado como bien dices, si en el procedimiento pongo la consulta a la tabla original directamente si que funciona, de modo que he puesto el profiler en marcha a ver que esta pasando por detras y el resultado es el siguiente (eliminando consultas innecesarias)

    use [AdventureWorksLT2008R2];
    GO
    SET FMTONLY OFF; SET FMTONLY ON;
    GO
    exec AdventureWorksLT2008R2.dbo.Prueba 
    GO
    SET FMTONLY OFF;
    GO

    De modo que entityFramwework, parece que establece la BBDD que toca y luego llama al procedimiento, pero antes hace algo muy curioso.

    La linea FMTONLY ON, lo que hace es que solo se retorne la informacion de metadatos de las columnas evitando obtener la consulta entera (supongo que lo hace por optimizar), pero claro, si se ejecuta esta consulta sobre una tabla temporal dara error, ya que no encuentra la tabla en el sistema para obtener los metadatos.

    De modo que si quieres usar la tabla temporal, debes insertar en el procedimiento almacenado la clausula:

    	-- obtener siempre los resultados de la consulta (evitar obtener metadatos unicamente)
    	SET FMTONLY OFF;

    Esto fuerza a ejecutar la consulta y retornarla, de modo que entityframework ya podra obtener las columnas.

    Pruebalo y me cuentas


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    • Marcado como respuesta Carlos Adrián jueves, 23 de febrero de 2012 11:20
    jueves, 23 de febrero de 2012 11:17

Todas las respuestas

  • Hola Carlos.

    Generalmente para estos casos en los que no se puede crear la entidad compleja, suelo parchear la consulta para obtener los datos que yo quiera (aunque lo hago cuando no dispongo de alguna BBDD asociada).

    Pero en tu caso, aunque puedes parchearlo como te he comentado antes, me ha intrigado y he analizado el proceso, el resultado es el siguiente:

    He creado un procedimiento llamado prueba (uno sencillo que crea una tabla temporal para obtener los datos:

    ALTER PROCEDURE [dbo].[Prueba] 
    AS
    BEGIN
    	-- Prevenir resultados extra
    	SET NOCOUNT ON;
    
    	-- crear tabla temporal
    	CREATE TABLE #prods (CustomerID int, FirstName nvarchar(50))
    	-- inertar tabla en la temporal
    	insert into #prods select CustomerID, FirstName from SalesLT.Customer
    	
    	
    	-- realizar la consulta sobre la tabla temporal
    	select CustomerID, FirstName from #prods
    	
    END

    Luego he intentado importar la funcion y no retorna ningun resultado como bien dices, si en el procedimiento pongo la consulta a la tabla original directamente si que funciona, de modo que he puesto el profiler en marcha a ver que esta pasando por detras y el resultado es el siguiente (eliminando consultas innecesarias)

    use [AdventureWorksLT2008R2];
    GO
    SET FMTONLY OFF; SET FMTONLY ON;
    GO
    exec AdventureWorksLT2008R2.dbo.Prueba 
    GO
    SET FMTONLY OFF;
    GO

    De modo que entityFramwework, parece que establece la BBDD que toca y luego llama al procedimiento, pero antes hace algo muy curioso.

    La linea FMTONLY ON, lo que hace es que solo se retorne la informacion de metadatos de las columnas evitando obtener la consulta entera (supongo que lo hace por optimizar), pero claro, si se ejecuta esta consulta sobre una tabla temporal dara error, ya que no encuentra la tabla en el sistema para obtener los metadatos.

    De modo que si quieres usar la tabla temporal, debes insertar en el procedimiento almacenado la clausula:

    	-- obtener siempre los resultados de la consulta (evitar obtener metadatos unicamente)
    	SET FMTONLY OFF;

    Esto fuerza a ejecutar la consulta y retornarla, de modo que entityframework ya podra obtener las columnas.

    Pruebalo y me cuentas


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    • Marcado como respuesta Carlos Adrián jueves, 23 de febrero de 2012 11:20
    jueves, 23 de febrero de 2012 11:17
  • ¡Eres un crack! :)

    Hoy no me da tiempo a probarlo, pero te digo ya que me cuadra mucho que sea algo así...

    Muchísimas gracias


    Carlos Adrián Martínez

    jueves, 23 de febrero de 2012 11:19
  • Comprobado!!! Funciona!!! Eres un máquina :)

    Por cierto, ya que te pones, tengo por ahí otros dos temas en el foro que nadie me ha sabido contestar, si un día te pica la curiosidad con ellos y me das una respuesta tan buena como la de las tablas temporales, te lo agradeceré mucho :)

    http://social.msdn.microsoft.com/Forums/es-ES/wpfes/thread/f8d654d6-818f-4f38-963c-f9b67e781fd2

    http://social.msdn.microsoft.com/Forums/es-ES/wpfes/thread/07df5e13-7661-4e92-9afb-af52b7df66ef

    Muchas gracias!!!!!


    Carlos Adrián Martínez

    jueves, 23 de febrero de 2012 13:24