共用方式為


資料來源控制項如何建立資料繫結欄位的參數

更新:2007 年 11 月

當您搭配 ASP.NET 資料來源控制項,使用像是 GridViewDetailsViewFormView 的資料繫結控制項時,資料繫結控制項會根據其中的繫結欄位,將參數名稱和值傳遞給資料來源控制項。資料來源控制項就會在 Select 或 Update 作業的參數集合中包含這些欄位名稱和值。如需詳細資訊,請參閱使用參數和 SqlDataSource 控制項使用參數和 ObjectDataSource 控制項

傳遞給資料來源控制項的字典

當資料繫結控制項從資料來源控制項要求作業時,會傳遞一個或多個包含所要求資料作業之參數名稱和值的 IDictionary 集合。在字典中,名稱/值組的值是衍生自子控制項。例如在 Update 作業中,資料繫結控制項會從以編輯模式顯示的 TextBoxCheckBox 控制項讀取參數值。名稱/值組的名稱是從繫結至子控制項,以及 DataKeyNames 屬性中指定的欄位名稱取得。針對 Update 或 Delete 作業,資料繫結控制項可能也會傳遞包含資料錄原始值的字典。

名稱/值組會使用下列 IDictionary 集合傳遞:

  • Values 集合:Insert 作業時傳遞,包含新資料錄的名稱/值組。Values 集合的欄位名稱和值是從 InsertItemTemplate 中的子控制項,或是從 InsertVisible 屬性設定為 true 之 DetailsView 控制項中的繫結欄位取得。

  • Keys 集合:Update 和 Delete 作業時傳遞,包含主要索引鍵,或是要更新或刪除之資料錄的索引鍵。如果可以修改資料來源的索引鍵欄位,Keys 集合也包含索引鍵欄位的原始值。當您將資料來源控制項的資料填入資料繫結控制項時,就會在檢視狀態維護資料。當要求 Update 或 Delete 作業時,就會使用之前儲存在檢視狀態中的值填入 Keys 集合。如果資料繫結控制項的 EnableViewState 屬性設定為 false,Update 或 Delete 作業就不會填入 Keys 集合。

  • NewValues 集合:Update 作業時傳遞,包含使用更新項目新值的名稱/值組,其中包括可更新索引鍵欄位的新值。NewValues 集合的欄位名稱和值是從 EditItemTemplate 中的子控制項,或是 ReadOnly 屬性設定為 false 的 DetailsView 控制項繫結欄位取得。

  • OldValues 集合:Update 或 Delete 作業時傳遞,包含資料錄的原始值以便用來進行開放式並行存取檢查 (如需開放式並行存取檢查的資訊,請參閱所使用之資料來源控制項的 ConflictDetection 屬性)。DataKeyNames 屬性識別的索引鍵欄位值,並未包含在 OldValues 集合中。索引鍵欄名稱和值只包含在 Keys 集合中。當您將資料來源控制項的資料填入資料繫結控制項時,就會在檢視狀態維護資料。當要求 Update 或 Delete 作業時,就會使用之前儲存在檢視狀態中的值填入 OldValues 集合。如果資料繫結控制項的 EnableViewState 屬性設定為 false,Update 或 Delete 作業就不會填入 OldValues 集合。

您可以使用與要求作業的資料繫結控制項事件一起傳遞的引數,存取所有的集合。例如,在 GridView 控制項的 RowUpdating 事件中,GridViewUpdateEventArgs 類別會提供 NewValues 集合的存取。

參數名稱

資料來源控制項會自動為 IDictionary 集合中傳遞的值建立參數。資料來源控制項會針對 Insert 作業,使用來自 Values 集合中名稱/值組的值填入 InsertParameters 集合。資料來源控制項會針對 Update 作業,使用來自 Keys、NewValues 和 OldValues 集合中名稱/值組的值填入 UpdateParameters 集合。資料來源控制項會針對 Delete 作業,使用來自 Keys 和 OldValues 集合中名稱/值組的值填入 DeleteParameters 集合。

OldValues 集合依預設不會填入。只有在資料來源控制項的 ConflictDetection 屬性設定為 CompareAllValues 時才會填入。

對於更新或刪除作業而言,預設只會建立目前繫結值的參數。如果您需要存取目前和原始的繫結值 (例如,支援開放式並行存取 (Optimistic Concurrency) 檢查),則可以讓資料來源控制項建立目前和原始值的參數。若要這麼做,您必須替將包含原始值的參數建立命名規範。原始值的參數格式是由 OldValuesParameterFormatString 屬性決定。將 OldValuesParameterFormatString 屬性設定為包含 "{0}" 當做欄位名稱替代符號的字串。例如,您使用的是 SqlDataSource 控制項,而且如果您將 OldValuesParameterFormatString 屬性設定為 "old_{0}",原始實值參數的名稱將解析為使用 "@old_" 當做前置字元的欄位名稱 (SqlDataSource 控制項會將 "@" 字元附加至所有參數名稱的開頭)。請考慮牽涉名為 LastModifiedDate 的欄位更新作業。欄位目前的值會在 Values 字典中傳遞,並且欄位的原始值會在 OldValues 字典中傳遞。還會建立名為 @LastModifiedDate 的參數傳遞目前的值,並且建立名為 @old\_LastModifiedDate 的參數傳遞原始值。然後可以在 SQL 陳述式中同時包含兩種參數,區分欄位目前的值和原始值,如同下列程式碼範例所示:

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

您不需要直接存取名稱/值 IDictionary 集合。只要在 SQL 陳述式中包含自動產生的參數名稱 (如果資料來源支援具名參數),或是做為使用 ObjectDataSource 控制項存取之商務物件中資料方法的參數名稱。

您可以選擇性地在資料來源控制項的 UpdateParameters、InsertParameters 或 DeleteParameters 集合中定義 Parameter 物件,以便自訂資料繫結控制項傳遞的值。您可以建立 Parameter 物件以便強型別值或指定預設值 (如果傳遞 null 的話)。

下列程式碼範例示範繫結至 SqlDataSource 控制項的 DetailsView 控制項。SqlDataSource 控制項的 InsertCommandUpdateCommandDeleteCommand 屬性會使用 SqlDataSource 控制項自動產生的參數名稱。根據 Keys 和 NewValues 字典填入參數值。因為 ConflictDetection 屬性值依預設會設定為 ConflictOptions.OverwriteChanges,所以不會使用 OldValues 字典。

<%@ 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>

請參閱

概念

使用含有資料來源控制項的參數

使用參數和 SqlDataSource 控制項

使用參數和 ObjectDataSource 控制項

資料來源控制項概觀