Estoy utilizando Linq-to-SQL con un servidor SQL Server (por supuesto) como un ORM para un proyecto. Necesito obtener el conjunto de resultados de un procedimiento almacenado que regresa de una tabla creada dinámicamente. Esto es lo que ve el proc como:¿Cómo obtengo Linq to SQL para reconocer el conjunto de resultados de un Procedimiento almacenado dinámico?
CREATE procedure [RetailAdmin].[TitleSearch] (
@isbn varchar(50), @author varchar(50),
@title varchar(50))
as
declare @L_isbn varchar(50)
declare @l_author varchar(50)
declare @l_title varchar(50)
declare @sql nvarchar(4000)
set @L_isbn = rtrim(ltrim(@isbn))
set @l_author = rtrim(ltrim(@author))
set @l_title = rtrim(ltrim(@title))
CREATE TABLE #mytemp(
[storeid] int not NULL,
[Author] [varchar](100) NULL,
[Title] [varchar](400) NULL,
[ISBN] [varchar](50) NULL,
[Imprint] [varchar](255) NULL,
[Edition] [varchar](255) NULL,
[Copyright] [varchar](100) NULL,
[stockonhand] [int] NULL
)
set @sql = 'select a.storeid, Author,Title, thirteendigitisbn ISBN,
Imprint,Edition,Copyright ,b.stockonhand from ods.items a join ods.inventory b on
a.itemkey = b.itemkey where b.stockonhand <> 0 '
if len(@l_author) > 0
set @sql = @sql + ' and author like ''%'[email protected]_author+'%'''
if len(@l_title) > 0
set @sql = @sql + ' and title like ''%'[email protected]_title+'%'''
if len(@L_isbn) > 0
set @sql = @sql + ' and thirteendigitisbn like ''%'[email protected]_isbn+'%'''
print @sql
if len(@l_author) <> 0 or len(@l_title) <> 0 or len(@L_isbn) <> 0
begin
insert into #mytemp
EXECUTE sp_executesql @sql
end
select * from #mytemp
drop table #mytemp
no he escrito este procedimiento, pero puede ser capaz de influir en un cambio si hay un problema muy serio.
Mi problema actual es que cuando agrego este procedimiento para mi modelo, el diseñador genera esta función:
[Function(Name="RetailAdmin.TitleSearch")]
public int TitleSearch([Parameter(DbType="VarChar(50)")] string isbn,
[Parameter(DbType="VarChar(50)")] string author,
[Parameter(DbType="VarChar(50)")] string title)
{
IExecuteResult result = this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())), isbn, author, title);
return ((int)(result.ReturnValue));
}
que no se parece en nada el conjunto de resultados que consigo cuando corro el proc de forma manual:
¿Puede alguien decirme lo que va mal aquí?
Esto es básicamente el mismo problema que this question pero debido a la mala redacción de la OP nunca fue realmente respondida.
Gracias Marc por su respuesta. Me ocuparé de hacer los cambios que sugirió.
El problema era la tabla temporal. Linq to Sql simplemente no sabe qué hacer con ellos. Esto fue particularmente difícil de diagnosticar, porque Visual Studio almacena en caché la información sobre los procesos almacenados, por lo que cuando inicialmente no pudo encontrar un conjunto de resultados estableció el retorno como un tipo de entero predeterminado y no se actualizó cuando realicé cambios en el proceso almacenado. Conseguir VS para reconocer un cambio requiere que:
- Eliminar proc del dbml
- eliminar la conexión del servidor desde el Explorador de servidores
- guardar el dbml para forzar una recompilación
- cerrar el proyecto y reiniciar VS
- recrear la conexión con el servidor e importar el proc
puede que no tenga que hacer cada uno de esos pasos, pero tha Es lo que funcionó para mí. Lo que debe hacer, si debe usar una tabla temporal, es crear un proceso barebone que simplemente devuelva el esquema correcto y luego modificarlo para hacer lo que desee después de importarlo en el Diseñador OR.
Los dos primeros puntos son importantes para esta pregunta en particular, pero en general creo que [SET FMTONLY ON] [http://msdn.microsoft.com/en-us/library/ms173839.aspx] es una parte central del problema cuando el código generado por LINQ to SQL no devuelve los resultados esperados. En algunos casos lo he configurado en OFF [http://www.fishofprey.com/2009/08/detecting-when-nettiers-is.html] cuando sé que el proceso almacenado no tendrá ningún efecto sobre los datos. Es decir. Solo selecciona. –