Condividi tramite


Come un controllo origine dati crea parametri per campi associati a dati

Aggiornamento: novembre 2007

Quando si utilizza un controllo con associazione a dati, ad esempio GridView, DetailsView o FormView, con un controllo origine dati ASP.NET, il controllo con associazione a dati è in grado di passare i nomi e i valori dei parametri al controllo origine dati in base ai campi associati al proprio interno. Il controllo origine dati include a sua volta i nomi e i valori dei campi nell'insieme dei parametri associati a operazioni di selezione o aggiornamento. Per ulteriori informazioni, vedere Utilizzo dei parametri con il controllo SqlDataSource e Utilizzo dei parametri con il controllo ObjectDataSource.

Dizionari passati ai controlli origine dati

Quando un controllo con associazione a dati richiede al controllo origine dati l'esecuzione di un'operazione, passa uno o più insiemi IDictionary contenenti i nomi e i valori dei parametri associati all'operazione sui dati richiesta. I valori delle coppie nome/valore presenti nel dizionario derivano dai controlli figlio. Ad esempio, in operazioni di aggiornamento, il controllo con associazione a dati legge i valori dei parametri dai i controlli TextBox o CheckBox visualizzati in modalità modifica. I nomi delle coppie nome/valore derivano dai nomi dei campi associati ai controlli figlio e dai nomi dei campi specificati nella proprietà DataKeyNames. Per operazioni di aggiornamento o eliminazione, il controllo con associazione a dati può inoltre passare un dizionario contenente i valori originali del record dati.

Le coppie nome/valore vengono passate utilizzando i seguenti insiemi IDictionary:

  • Insieme Values.   Passato per operazioni di inserimento. Contiene le coppie nome/valore per il nuovo record. I nomi e i valori del campo per l'insieme Values derivano dai controlli figlio presenti in un InsertItemTemplate o da campi associati presenti in un controllo DetailsView la cui proprietà InsertVisible è impostata su true.

  • Insieme Keys   Passato per operazioni di aggiornamento ed eliminazione. Contiene la chiave o le chiavi primarie per il record aggiornato o eliminato. Se è possibile modificare i campi chiave nell'origine dati, l'insieme Keys conterrà anche i valori originali di tali campi. Quando un controllo con associazione a dati è popolato con i dati provenienti dal controllo origine, esso mantiene quei dati nello stato di visualizzazione. Per operazioni di aggiornamento o eliminazione, l'insieme Keys viene popolato con i valori archiviati precedentemente nello stato di visualizzazione. Se la proprietà EnableViewState del controllo con associazione a dati è impostata su false, l'insieme Keys non verrà popolato per operazioni di aggiornamento o eliminazione.

  • Insieme NewValues   Passato per operazioni di aggiornamento. Contiene le coppie nome/valore con i nuovi valori per l'elemento aggiornato, compresi i nuovi valori per i campi chiave aggiornabili. I nomi e i valori dei campi per l'insieme NewValues derivano dai controlli figlio presenti in un EditItemTemplate o dai campi associati in un controllo DetailsView la cui proprietà ReadOnly è impostata su false.

  • Insieme OldValues   Passato per operazioni di aggiornamento o eliminazione. Contiene i valori originali per il record dati da utilizzare per la verifica di concorrenza ottimistica. (Per informazioni relative alla verifica di concorrenza ottimistica, vedere la proprietà ConflictDetection del controllo origine dati utilizzato). I valori per i campi chiave identificati dalla proprietà DataKeyNames non sono inclusi nell'insieme OldValues. I nomi e i valori del campo o dei campi chiave sono inclusi solamente nell'insieme Keys. Quando un controllo con associazione a dati è popolato con i dati provenienti dal controllo origine, esso mantiene quei dati nello stato di visualizzazione. Per operazioni di aggiornamento o eliminazione, l'insieme OldValues viene popolato con i valori archiviati precedentemente nello stato di visualizzazione. Se la proprietà EnableViewState del controllo con associazione a dati è impostata su false, l'insieme OldValues non verrà popolato per operazioni di aggiornamento o eliminazione.

È possibile accedere a tutti questi insiemi utilizzando gli argomenti passati con l'evento del controllo con associazione a dati per l'operazione richiesta. Ad esempio, nell'evento RowUpdating del controllo GridView, la classe GridViewUpdateEventArgs consente l'accesso all'insieme NewValues.

Nomi dei parametri

Il controllo origine dati genera automaticamente i parametri per i valori passati negli insiemi IDictionary. Per operazioni di inserimento, il controllo origine dati popola il proprio insieme InsertParameters con i valori provenienti dalle coppie nome/valore presenti nell'insieme Values. Per operazioni di aggiornamento, il controllo origine dati popola il proprio insieme UpdateParameters con i valori provenienti dalle coppie nome/valore presenti negli insiemi Keys, NewValues eOldValues. Per operazioni di eliminazione, il controllo origine dati popola il proprio insieme DeleteParameters con i valori provenienti dalle coppie nome/valore presenti negli insiemi Keys e OldValues.

L'insieme OldValues non è popolato per impostazione predefinita. Esso viene popolato solo quando la proprietà ConflictDetection del controllo origine dati è impostata su CompareAllValues.

Nel caso delle operazioni di aggiornamento o eliminazione, per impostazione predefinita vengono creati solo i parametri relativi ai valori associati correnti. Se si è in grado di accedere sia ai valori associati correnti sia a quelli originali (ad esempio per supportare i controlli della concorrenza ottimistica) è possibile fare in modo che il controllo di origine dati crei parametri per entrambi i tipi di valore. A tale scopo, è necessario stabilire una convenzione di denominazione per i parametri che conterranno valori originali. Il formato dei parametri per i valori originali è determinato dalla proprietà OldValuesParameterFormatString. Impostare la proprietà OldValuesParameterFormatString su una stringa in cui "{0}" è un segnaposto per il nome del campo. Se ad esempio si utilizza il controllo SqlDataSource e si imposta la proprietà OldValuesParameterFormatString su "old_{0}", i nomi dei parametri dei valori originali si risolveranno nel nome del campo con prefisso "@old_". Il controllo SqlDataSource aggiunge un carattere "@" all'inizio di tutti i nomi di parametri. Si consideri un'operazione di aggiornamento che riguarda un campo denominato LastModifiedDate. Il valore corrente relativo al campo viene passato nel dizionario Values, mentre il valore originale viene passato nel dizionario OldValues. Per passare il valore corrente viene creato un parametro denominato @LastModifiedDate, mentre per passare il valore originale viene creato un parametro denominato @old\_LastModifiedDate. È quindi possibile includere entrambi i parametri in un'istruzione SQL per distinguere il valore originale da quello corrente, come illustrato nell'esempio riportato di seguito:

UPDATE Table1 SET LastModifiedDate = @LastModifiedDate
  WHERE Key = @Key AND LastModifiedDate = @old_LastModifiedDate

Non è necessario accedere direttamente agli insiemi IDictionary nome/valore. È sufficiente includere i nomi dei parametri generati automaticamente nelle istruzioni SQL (se l'origine dati supporta i parametri denominati) o i nomi dei parametri dei metodi dati di un oggetto business a cui si accede tramite un controllo ObjectDataSource.

Se lo si desidera, è possibile definire oggetti Parameter negli insiemi UpdateParameters, InsertParameters, o DeleteParameters del controllo origine dati per personalizzare i valori passati dal controllo con associazione a dati. È inoltre possibile creare oggetti Parameter in modo da tipizzare fortemente i valori, oppure per specificare un valore predefinito se viene passato null.

Il codice di esempio riportato di seguito mostra un controllo DetailsView associato a un controllo SqlDataSource. Le proprietà InsertCommand, UpdateCommand e DeleteCommand del controllo SqlDataSource utilizzano i nomi dei parametri generati automaticamente dal controllo SqlDataSource. I valori dei parametri sono popolati in base ai dizionari Keys e NewValues. Il dizionario OldValues non è utilizzato perché la proprietà ConflictDetection è impostata su ConflictOptions.OverwriteChanges, che è l'impostazione predefinita.

<%@ Page language="VB" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script >

  Sub EmployeesDropDownList_OnSelectedIndexChanged(sender As Object, e As EventArgs)
    EmployeeDetailsView.DataBind()
  End Sub

  Sub EmployeeDetailsView_ItemUpdated(sender As Object, e As DetailsViewUpdatedEventArgs)
    EmployeesDropDownList.DataBind()
    EmployeesDropDownList.SelectedValue = e.Keys("EmployeeID").ToString()
    EmployeeDetailsView.DataBind()
  End Sub

  Sub EmployeeDetailsView_ItemDeleted(sender As Object, e As DetailsViewDeletedEventArgs)
    EmployeesDropDownList.DataBind()
  End Sub

  Sub EmployeeDetailsSqlDataSource_OnInserted(sender As Object, e As SqlDataSourceStatusEventArgs)
    Dim command As System.Data.Common.DbCommand = e.Command  
    EmployeesDropDownList.DataBind()
    EmployeesDropDownList.SelectedValue = _
      command.Parameters("@EmpID").Value.ToString()
    EmployeeDetailsView.DataBind()
  End Sub

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
  <head >
    <title>Northwind Employees</title>
</head>
<body>
    <form id="form1" >

      <h3>Northwind Employees</h3>

        <table cellspacing="10">

          <tr>
            <td valign="top">
              <asp:DropDownList ID="EmployeesDropDownList" 
                DataSourceID="EmployeesSqlDataSource" 
                DataValueField="EmployeeID" 
                DataTextField="FullName"
                AutoPostBack="True"
                OnSelectedIndexChanged="EmployeesDropDownList_OnSelectedIndexChanged"
                RunAt="Server" />            
            </td>

            <td valign="top">                
              <asp:DetailsView ID="EmployeeDetailsView"
                DataSourceID="EmployeeDetailsSqlDataSource"
                AutoGenerateRows="false"
                AutoGenerateInsertbutton="true"
                AutoGenerateEditbutton="true"
                AutoGenerateDeletebutton="true"
                DataKeyNames="EmployeeID"     
                Gridlines="Both"
                OnItemUpdated="EmployeeDetailsView_ItemUpdated"
                OnItemDeleted="EmployeeDetailsView_ItemDeleted"      
                RunAt="server">

                <HeaderStyle backcolor="Navy"
                  forecolor="White"/>

                <RowStyle backcolor="White"/>

                <AlternatingRowStyle backcolor="LightGray"/>

                <EditRowStyle backcolor="LightCyan"/>

                <Fields>                  
                  <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" InsertVisible="False" ReadOnly="true"/>                    
                  <asp:BoundField DataField="FirstName"  HeaderText="First Name"/>
                  <asp:BoundField DataField="LastName"   HeaderText="Last Name"/>                    
                  <asp:BoundField DataField="Address"    HeaderText="Address"/>                    
                  <asp:BoundField DataField="City"       HeaderText="City"/>                        
                  <asp:BoundField DataField="Region"     HeaderText="Region"/>
                  <asp:BoundField DataField="PostalCode" HeaderText="Postal Code"/>                    
                </Fields>                    
              </asp:DetailsView>
            </td>                
          </tr>            
        </table>

        <asp:SqlDataSource ID="EmployeesSqlDataSource"  
          SelectCommand="SELECT EmployeeID, LastName + ', ' + FirstName AS FullName FROM Employees" 
          Connectionstring="<%$ ConnectionStrings:NorthwindConnection %>" 
          RunAt="server">
        </asp:SqlDataSource>


        <asp:SqlDataSource ID="EmployeeDetailsSqlDataSource" 
          SelectCommand="SELECT EmployeeID, LastName, FirstName, Address, City, Region, PostalCode
                         FROM Employees WHERE EmployeeID = @EmpID"

          InsertCommand="INSERT INTO Employees(LastName, FirstName, Address, City, Region, PostalCode)
                         VALUES (@LastName, @FirstName, @Address, @City, @Region, @PostalCode); 
                         SELECT @EmpID = SCOPE_IDENTITY()"

          UpdateCommand="UPDATE Employees SET LastName=@LastName, FirstName=@FirstName, Address=@Address,
                           City=@City, Region=@Region, PostalCode=@PostalCode
                         WHERE EmployeeID=@EmployeeID"

          DeleteCommand="DELETE Employees WHERE EmployeeID=@EmployeeID"

          ConnectionString="<%$ ConnectionStrings:NorthwindConnection %>"
          OnInserted="EmployeeDetailsSqlDataSource_OnInserted"
          RunAt="server">

          <SelectParameters>
            <asp:ControlParameter ControlID="EmployeesDropDownList" PropertyName="SelectedValue"
                                  Name="EmpID" Type="Int32" DefaultValue="0" />
          </SelectParameters>

          <InsertParameters>
            <asp:Parameter Name="LastName"   Type="String" />
            <asp:Parameter Name="FirstName"  Type="String" />
            <asp:Parameter Name="Address"    Type="String" />
            <asp:Parameter Name="City"       Type="String" />
            <asp:Parameter Name="Region"     Type="String" />
            <asp:Parameter Name="PostalCode" Type="String" />
            <asp:Parameter Name="EmpID" Direction="Output" Type="Int32" DefaultValue="0" />
          </InsertParameters>

          <UpdateParameters>
            <asp:Parameter Name="LastName"   Type="String" />
            <asp:Parameter Name="FirstName"  Type="String" />
            <asp:Parameter Name="Address"    Type="String" />
            <asp:Parameter Name="City"       Type="String" />
            <asp:Parameter Name="Region"     Type="String" />
            <asp:Parameter Name="PostalCode" Type="String" />
            <asp:Parameter Name="EmployeeID" Type="Int32" DefaultValue="0" />
          </UpdateParameters>

          <DeleteParameters>
            <asp:Parameter Name="EmployeeID" Type="Int32" DefaultValue="0" />
          </DeleteParameters>

        </asp:SqlDataSource>
      </form>
  </body>
</html>
<%@ Page language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script >

  void EmployeesDropDownList_OnSelectedIndexChanged(Object sender, EventArgs e)
  {
    EmployeeDetailsView.DataBind();
  }

  void EmployeeDetailsView_ItemUpdated(Object sender, DetailsViewUpdatedEventArgs e)
  {
    EmployeesDropDownList.DataBind();
    EmployeesDropDownList.SelectedValue = e.Keys["EmployeeID"].ToString();
    EmployeeDetailsView.DataBind();
  }

  void EmployeeDetailsView_ItemDeleted(Object sender, DetailsViewDeletedEventArgs e)
  {
    EmployeesDropDownList.DataBind();
  }

  void EmployeeDetailsSqlDataSource_OnInserted(Object sender, SqlDataSourceStatusEventArgs e)
  {
    System.Data.Common.DbCommand command = e.Command;   
    EmployeesDropDownList.DataBind();
    EmployeesDropDownList.SelectedValue = 
      command.Parameters["@EmpID"].Value.ToString();
    EmployeeDetailsView.DataBind();
  }

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
  <head >
    <title>Northwind Employees</title>
</head>
<body>
    <form id="form1" >

      <h3>Northwind Employees</h3>

        <table cellspacing="10">

          <tr>
            <td valign="top">
              <asp:DropDownList ID="EmployeesDropDownList" 
                DataSourceID="EmployeesSqlDataSource" 
                DataValueField="EmployeeID" 
                DataTextField="FullName"
                AutoPostBack="True"
                OnSelectedIndexChanged="EmployeesDropDownList_OnSelectedIndexChanged"
                RunAt="Server" />            
            </td>

            <td valign="top">                
              <asp:DetailsView ID="EmployeeDetailsView"
                DataSourceID="EmployeeDetailsSqlDataSource"
                AutoGenerateRows="false"
                AutoGenerateInsertbutton="true"
                AutoGenerateEditbutton="true"
                AutoGenerateDeletebutton="true"
                DataKeyNames="EmployeeID"     
                Gridlines="Both"
                OnItemUpdated="EmployeeDetailsView_ItemUpdated"
                OnItemDeleted="EmployeeDetailsView_ItemDeleted"      
                RunAt="server">

                <HeaderStyle backcolor="Navy"
                  forecolor="White"/>

                <RowStyle backcolor="White"/>

                <AlternatingRowStyle backcolor="LightGray"/>

                <EditRowStyle backcolor="LightCyan"/>

                <Fields>                  
                  <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID" InsertVisible="False" ReadOnly="true"/>                    
                  <asp:BoundField DataField="FirstName"  HeaderText="First Name"/>
                  <asp:BoundField DataField="LastName"   HeaderText="Last Name"/>                    
                  <asp:BoundField DataField="Address"    HeaderText="Address"/>                    
                  <asp:BoundField DataField="City"       HeaderText="City"/>                        
                  <asp:BoundField DataField="Region"     HeaderText="Region"/>
                  <asp:BoundField DataField="PostalCode" HeaderText="Postal Code"/>                    
                </Fields>                    
              </asp:DetailsView>
            </td>                
          </tr>            
        </table>

        <asp:SqlDataSource ID="EmployeesSqlDataSource"  
          SelectCommand="SELECT EmployeeID, LastName + ', ' + FirstName AS FullName FROM Employees" 
          Connectionstring="<%$ ConnectionStrings:NorthwindConnection %>" 
          RunAt="server">
        </asp:SqlDataSource>


        <asp:SqlDataSource ID="EmployeeDetailsSqlDataSource" 
          SelectCommand="SELECT EmployeeID, LastName, FirstName, Address, City, Region, PostalCode
                         FROM Employees WHERE EmployeeID = @EmpID"

          InsertCommand="INSERT INTO Employees(LastName, FirstName, Address, City, Region, PostalCode)
                         VALUES (@LastName, @FirstName, @Address, @City, @Region, @PostalCode); 
                         SELECT @EmpID = SCOPE_IDENTITY()"

          UpdateCommand="UPDATE Employees SET LastName=@LastName, FirstName=@FirstName, Address=@Address,
                           City=@City, Region=@Region, PostalCode=@PostalCode
                         WHERE EmployeeID=@EmployeeID"

          DeleteCommand="DELETE Employees WHERE EmployeeID=@EmployeeID"

          ConnectionString="<%$ ConnectionStrings:NorthwindConnection %>"
          OnInserted="EmployeeDetailsSqlDataSource_OnInserted"
          RunAt="server">

          <SelectParameters>
            <asp:ControlParameter ControlID="EmployeesDropDownList" PropertyName="SelectedValue"
                                  Name="EmpID" Type="Int32" DefaultValue="0" />
          </SelectParameters>

          <InsertParameters>
            <asp:Parameter Name="LastName"   Type="String" />
            <asp:Parameter Name="FirstName"  Type="String" />
            <asp:Parameter Name="Address"    Type="String" />
            <asp:Parameter Name="City"       Type="String" />
            <asp:Parameter Name="Region"     Type="String" />
            <asp:Parameter Name="PostalCode" Type="String" />
            <asp:Parameter Name="EmpID" Direction="Output" Type="Int32" DefaultValue="0" />
          </InsertParameters>

          <UpdateParameters>
            <asp:Parameter Name="LastName"   Type="String" />
            <asp:Parameter Name="FirstName"  Type="String" />
            <asp:Parameter Name="Address"    Type="String" />
            <asp:Parameter Name="City"       Type="String" />
            <asp:Parameter Name="Region"     Type="String" />
            <asp:Parameter Name="PostalCode" Type="String" />
            <asp:Parameter Name="EmployeeID" Type="Int32" DefaultValue="0" />
          </UpdateParameters>

          <DeleteParameters>
            <asp:Parameter Name="EmployeeID" Type="Int32" DefaultValue="0" />
          </DeleteParameters>

        </asp:SqlDataSource>
      </form>
  </body>
</html>

Vedere anche

Concetti

Utilizzo di parametri con controlli origine dati

Utilizzo dei parametri con il controllo SqlDataSource

Utilizzo dei parametri con il controllo ObjectDataSource

Cenni preliminari sui controlli origine dati