2010-07-13 18 views
7

En el código subyacente debe agregar TVP como SqlDbType.Structured para un procedimiento almacenado Pero esto no existe en un control ASP.NET SqlDataSource.Cómo configurar ASP.NET SQL Datasource para aceptar TVP

que he guardado mis tablas de datos en variables de sesión (no se preocupe, que son pequeños!) Y me tienen que pasar los parámetros como a la SqlDataSource (que tiene una serie de objetos de enlace de datos)

Señalé el origen de datos a la variable de sesión pero falla en la conversión al tipo de tabla.

EDIT: Digamos que tomo la variable de sesión fuera de la ecuación (porque, en realidad, es completamente tangencial)

Tiene que haber una manera de que pueda adjuntar una DBType.Structured a un SQLDataSource. Mis vistas de lista están apropiadamente enlazadas a datos pero los procedimientos de almacenamiento a los que están conectadas deben tomar TVP's

No puedo creer que no haya forma de enviar un parámetro TVP para un SQLDataSource? ¿Cuáles son mis alternativas?

Edit2: He estado buscando en la creación de un parámetro personalizado para el SqlDataSource pero todavía parece a mí como su método "eval" no va a ser feliz con el tipo de datos estructurado

Edit3: Es comenzando a parecer que mi única opción es hacer todo el trabajo en código subyacente para mis controles de datos. Agregué una recompensa en caso de que alguien más tenga una solución elegante.

EDIT4: ¿Existe alguna forma de pasar la tabla como objeto de un procedimiento almacenado y que SQL Server la convierta a TVP?

+1

Hay una serie de razones por las que muy pocas personas todavía usan esos controles, y por qué las personas no almacenan las tablas de datos en sesión. Puede ser el momento de pasar al siguiente paso en su educación de desarrollo. – NotMe

+2

Entiendo las razones en contra de almacenar tablas de datos en sesiones; este es un ambiente controlado donde mi uso es apropiado. En cuanto a su afirmación de que "muy pocas personas todavía usan esos controles", nunca escuché eso. ¿Sugiere que hay un problema inherente con el uso del control SqlDataSource? Considerando que funciona bastante bien en casi todas las situaciones para las que fue diseñado, no veo su punto en contra. Por otro lado, estoy abierto a sus sugerencias sobre cómo vincular mejor controles múltiples a datos tan elegantemente como el SqlDataSource – Matthew

+1

El SqlDataSource es anterior a la tabla de parámetros valorados por un número significativo de años, no me sorprendería que el la capacidad no existe y no ha sido agregada. – womp

Respuesta

4

Sé que ha editado para decir que la sesión no tiene importancia, sin embargo, pude hacer que esto funcionara usando un parámetro SessionParameter. Tengo la sensación de que también funcionaría con un ControlParameter.

lo que tiene una definida por el usuario tipo de tabla:

CREATE TYPE TVPType AS TABLE(
    Col1 int, 
    Col2 int) 
GO 

y un procedimiento almacenado que lo utiliza:

CREATE PROC TVPProc(@TVP AS TVPType READONLY) AS 
    SELECT * FROM @TVP 

entonces un GridView unido a un SqlDataSource que selecciona desde su sproc, pasando a SessionParameter:

<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" /> 
<asp:SqlDataSource ID="SqlDataSource1" SelectCommand="TVPProc" runat="server" SelectCommandType="StoredProcedure" ConnectionString="Server=(local)\sqlexpress;Database=Graph;Integrated Security=True"> 
    <SelectParameters> 
     <asp:SessionParameter SessionField="MyDataTable" Name="TVP" /> 
    </SelectParameters> 
</asp:SqlDataSource> 

y finalmente algo para poner un DataTable i nto de la sesión, a pesar de que se dice que ya lo tienen allí de todos modos:

(VB)

<script runat="server"> 
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) 
     Dim MyDataTable As New System.Data.DataTable 

     MyDataTable.Columns.AddRange({ 
      New System.Data.DataColumn("Col1", GetType(integer)), 
      New System.Data.DataColumn("Col2", GetType(integer))}) 

     MyDataTable.Rows.Add(22, 33) 
     MyDataTable.Rows.Add(44, 55) 
     MyDataTable.Rows.Add(66, 77) 

     Session("MyDataTable") = MyDataTable 
    End Sub 
</script> 

(C#)

<script runat="server"> 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     System.Data.DataTable MyDataTable = new System.Data.DataTable(); 
     MyDataTable.Columns.AddRange(
      new System.Data.DataColumn[] { 
       new System.Data.DataColumn("Col1", typeof (int)), 
       new System.Data.DataColumn("Col2", typeof (int))}); 

     MyDataTable.Rows.Add(22, 33); 
     MyDataTable.Rows.Add(44, 55); 
     MyDataTable.Rows.Add(66, 77); 

     Session["MyDataTable"] = MyDataTable; 
    } 
</script> 

que se traduce en un GridView finamente obligado:

alt text

y la siguiente consulta generada por el Analizador:

declare @p1 dbo.TVPType 
insert into @p1 values(22,33) 
insert into @p1 values(44,55) 
insert into @p1 values(66,77) 

exec TVPProc @[email protected] 

Esto es .NET 4, MSSQL Express 2010, pero debería funcionar más bajo también.

+0

Esto funciona! Parece que el problema es que la fuente de datos por defecto quiere un tipo de datos para los parámetros. Si se elimina y se borra deliberadamente, las funciones de los SD funcionan correctamente. Gracias He reactivado el bounty y marcado el suyo como la respuesta – Matthew

+0

Como una nota importante: Este * solo * parece funcionar con la opción de campo de sesión y sin ningún tipo especificado. Además, los campos de la sesión deben establecerse en una tabla de datos con las dimensiones correctas en la carga del formulario. Para dar cuenta de esto (en los casos donde los campos de sesión no son apropiados) establezco temporalmente un campo de sesión, vuelvo a vincular los controles, luego elimino el campo de sesión – Matthew

0

Crea una clase o adaptador intermediario que servirá como fuente para cualquier delimitación de datos automáticos que ya tengas. Entonces usted tiene el control total para preparar args para el sproc exactamente de la manera que lo necesita.

+0

Esto evade el uso del SDS con el TVP, ¿o no? Ya sé que puedo escribir clases para obtener mis objetos de datos ... el problema es alimentar las tablas de datos en el objeto de fuente de datos existente. – Matthew

+0

Cuando te enfrentas a capas hinchadas, el arte de la evasión es una gran virtud :-) Técnicamente, puedes derivar de SqlDataSourceView y anular ExecuteSelect, etc. para que aún se vea y grabe como SqlDataSourceView. Puede leer la implementación actual en Reflector y buscar un lugar para hacer el mod. – ZXX

Cuestiones relacionadas