Posts
103
Comments
238
Trackbacks
4
Ottenere il valore Identity da un DBDirect method di un TableAdapter

Background

  • Tabella SQL Server Express 2005 chiamata Clienti, per semplicità due colonne, una chiave primaria identità IdCliente, e due varchar, Nome e Cognome.
  • DataSet tipizzato (Clienti.xsd), DataTable (Clienti), TableAdapter (ClientiTableAdapter) e metodi DBDirect generati automaticamente con drag and drop da Object Browser
  • Aggiunta di una query di SELECT identica a quella generata automaticamente ma che accetta un parametro "IdCliente" (chiave primaria e identity) su cui filtrare
  • Una pagina contenente una FormView (o DetailsView per quel che importa) con ObjectDataSource che ottiene il parametro della query di select suddetta da QueryString per visualizzare i dati del Cliente desiderato (ci si arriva da un'altra pagina con una GridView con un HyperLink per ogni riga)
  • Se il parametro da QueryString è null si va direttamente in inserimento:

    if(!IsPostBack && Request.QueryString["IdCliente"] == null)
    {
        FormView1.ChangeMode(FormViewMode.Insert);
    }

Problemi

  • Se chiamo la pagina senza parametro da QueryString (e quindi vado in inserimento), inserisco i dati e salvo, la FormView va in EmptyDataTemplate
  • Se vado in modalità inserimento partendo dall'ItemTemplate di un altro record, dopo aver inserito i dati di quello nuovo mi torna al record che stavo visualizzando prima.

Comportamento desiderato

Indipendentemente dal percorso seguito per inserire il nuovo record vorrei che dopo averlo inserito la FormView restasse su quel record andando in ItemTemplate, cioè visualizzando i dati che ho appena inserito.

Soluzione

Nel DataSet designer aggiungo una nuova query di inserimento che ritorni il valore Identity del record appena inserito al TableAdapter in questione:

  • Click destro nel DataSet designer su ClientiTableAdapter
  • Add query -> Use SQL Statements -> Insert query
  • Ottengo una cosa di questo tipo (che è identica a quella generata automaticamente)

    INSERT INTO [Clienti] ([Nome], [Cognome])
    VALUES (@Nome@Cognome);

    SELECT IdClienteNomeCognome
    FROM Clienti WHERE (IdCliente SCOPE_IDENTITY())

  • Togliamo la seconda query e riscriviamo in questo modo:

    INSERT INTO [Clienti] ([Nome], [Cognome])
    VALUES (@Nome@Cognome);

    SELECT SCOPE_IDENTITY();
  • Chiamiamo il metodo "InserisciCliente", lo salviamo e nelle sue proprietà cambiamo l'ExcecuteMode da NonQuery a Scalar
  • Ora andiamo al nostro ObjectDataSource e gli diciamo di utilizzare quel metodo come inserimento (smart tag -> Configure DataSource)
  • Nelle sue proprietà (tab eventi) facciamo doppio click sul campo Inserted per creare un EventHandler appropriato. L'oggetto ObjectDataSourceStatusEventArgs contiene una proprietà chiamata ReturnValue, che guarda caso contiene proprio il valore IdCliente del record appena inserito. Nel mio caso lo utilizzo per fare un redirect alla stessa pagina passandoglielo come parametro di QueryString:

    protected void ObjectDataSource1_Inserted(object sender, ObjectDataSourceStatusEventArgs e)
    {
       Response.Redirect("DettagliCliente.aspx?IdCliente=" + e.ReturnValue, 
    false);
    }

powered by IMHO 1.3

posted on Monday, March 27, 2006 6:13 AM Print
News

Scopri CS2, il mio progetto universitario per l'indicizzazione e la ricerca di codice sorgente personale costruito su Lucene.Net.

Windows Developer Power Tools

Potete trovare il mio progetto BusyBoxDotNet nel libro Windows Developer Power Tools, pubblicato da O'Reilly, per il quale ho scritto l'intero capito dedicato.

Sono stato nominato dVP 2008, un riconoscimento per l'apporto fornito alla comunità del progetto db4o.