2010-07-13 8 views
7

Nel codebehind si aggiunge il TVP come SqlDbType.Structured per una stored procedure Ma questo non esiste in un controllo SqlDataSource di ASP.NET.Come configurare l'origine dati SQL ASP.NET per accettare TVP

ho conservato i miei DataTable nelle variabili di sessione (non preoccupatevi sono piccoli!) E ho bisogno di passare quelli come parametri per la SqlDataSource (che ha un certo numero di oggetti databound)

indicai l'origine dati alla variabile di sessione ma non riesce nella conversione al tipo di tabella.

EDIT: Diciamo che prendo la variabile di sessione fuori dall'equazione (perché, in realtà, è completamente tangenziale)

Ci deve essere un modo per collegare un DBType.Structured ad uno SQLDataSource. miei listviews sono adeguatamente databound ma le procedure del deposito a cui sono attaccati devono prendere di TVP

Non posso credere che non ci sarebbe alcun modo per inviare un paramater TVP per uno SQLDataSource? Quali sono le mie alternative?

EDIT2: Ho cercato nella creazione di un parametro personalizzato per lo SqlDataSource ma sembra ancora a me come il suo metodo "eval" non sarà felice con il tipo di dati strutturati

Edit3: E ' Comincio ad apparire che la mia unica opzione è fare tutto il lavoro in codebehind per i miei controlli di database. Ho aggiunto una taglia nel caso in cui qualcun altro abbia una soluzione elegante.

EDIT4: C'è forse un modo per passare la tabella come oggetto a una stored procedure, quindi SQL Server convertirlo in TVP?

+1

Esistono diversi motivi per cui pochissime persone utilizzano ancora tali controlli e perché le persone non memorizzano tabelle di dati in sessione. Potrebbe essere il momento di passare al prossimo passo nella tua educazione allo sviluppo. – NotMe

+2

Capisco le ragioni contro la memorizzazione di datatables nelle sessioni; questo è un ambiente controllato in cui il mio uso è appropriato. Per quanto riguarda la tua affermazione che "pochissime persone usano ancora quei controlli" non l'ho mai sentito. Stai suggerendo che c'è un problema inerente all'utilizzo del controllo SqlDataSource? Considerando che funziona abbastanza bene in quasi tutte le situazioni per cui è stato progettato, non riesco a vedere il tuo punto contro di esso. D'altra parte, sono aperto ai vostri suggerimenti su come associare più controlli ai dati in modo elegante come SqlDataSource – Matthew

+1

The SqlDataSource fa precedere i parametri valutati in tabella di un numero significativo di anni, non sarei sorpreso che il la capacità non esiste e non è stata aggiunta. – womp

risposta

4

So che hai modificato per dire che la sessione non ha importanza, tuttavia sono riuscito a farlo funzionare utilizzando un SessionParameter. Ho la sensazione che funzionerebbe anche con un ControlParameter.

in modo da avere un tipo di tabella definito dall'utente:

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

e una stored procedure che lo utilizza:

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

poi un GridView legato ad uno SqlDataSource che seleziona dal tuo sProc, passando 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> 

e infine un po 'di qualcosa per mettere un DataTable i nto la sessione, anche se si dice già lì comunque:

(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> 

che si traduce in un GridView finemente rilegato:

alt text

e la seguente query generata da Profiler:

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] 

Questo è .NET 4, MSSQL Express 2010, ma dovrebbe funzionare anche in basso.

+0

Funziona! Quindi sembra che il problema è che l'origine dati per impostazione predefinita vuole un tipo di dati per i parametri. Se viene rimosso e oscurato deliberatamente, le funzioni di sds funzionano correttamente. Grazie Ho riattivato il bounty e segnato il tuo come risposta – Matthew

+0

Come nota importante: Questo * solo * sembra funzionare con l'opzione del campo sessione e senza specificare il tipo. Inoltre, i campi di sessione devono essere impostati su un datatable delle dimensioni corrette sul caricamento del modulo. Per tener conto di ciò (nei casi in cui i campi di sessione non sono appropriati) imposto temporaneamente un campo sessione, ricollego i controlli, quindi rimuovo il campo sessione – Matthew

0

Crea una classe intermedia o un adattatore che servirà come fonte per qualsiasi limitazione automatica dei dati che hai già. Allora hai il pieno controllo per preparare gli argomenti per lo sproc esattamente come ne ha bisogno.

+0

Questo però evita l'uso della SDS con TVP, vero? So già che posso scrivere classi per l'origine dei miei oggetti del database ... il problema è alimentare i datatables nell'oggetto datasource esistente. – Matthew

+0

Quando ci si trova di fronte a strati gonfiati, l'arte dell'evasione è una grande virtù :-) Tecnicamente è possibile derivare da SqlDataSourceView e sovrascrivere ExecuteSelect ecc. In modo che assomigli ancora e cova come SqlDataSourceView. Puoi leggere l'implementazione corrente in Reflector e cercare un posto dove fare la mod. – ZXX

Problemi correlati