使用資料來源控制項處理 Null 資料庫值
更新:2007 年 11 月
在許多情況下,當沒有值存放在資料庫資料表的資料行時,該資料行便會傳回 null。然而,在您處理 ASP.NET 程式碼或資料繫結 Web 控制項時,null 值可能會受到質疑。例如,假設您試圖將 DropDownList 控制項的 SelectedValue 繫結為 null,則會擲回例外狀況 (Exception)。
ASP.NET 提供了一些處理 null 值的內建功能。如果使用內建的 ASP.NET 功能無法解決您的案例,有些額外的技巧是可以用來處理 null 值。
NullDisplayText 屬性
您可以在資料來源控制項 (例如 BoundField、CheckBoxField 和 ImageField 物件) 中設定繫結欄位的 NullDisplayText 屬性,進而以特定值 (如字串) 取代從資料來源傳回的 null 值。於是,控制項就會把該值顯示為繫結控制項的文字。在編輯作業期間修改資料繫結資料列時,如果繫結欄位的值與 NullDisplayText 相符 (不管是沒有修改過該值,或是使用者輸入了與 NullDisplayText 一樣的值),則欄位會將 null 傳遞給資料來源做為欄位值。如果沒有設定 NullDisplayText 屬性,則會將 null 值顯示為空字串 ("")。
例如,假設您將 BoundField 物件的 NullDisplayText 屬性設為 "(沒有值)",而且繫結資料欄位為 null,則會將 Label 的 Text 屬性或 BoundField 物件所呈現的 TextBox 物件設為 "(沒有值)"。如果使用者編輯資料列,並將值從 "(沒有值)" 變更為 "自訂值",則會將 "自訂值" 傳遞給資料來源做為欄位值。但如果繫結控制項的值還是 "(沒有值)",則資料控制項會將 null 傳遞給資料來源做為欄位值。
ConvertEmptyStringToNull 屬性
Parameter 物件、TemplateField 物件和繫結欄位 (BoundField、CheckBoxField、ImageField 和 AutoGeneratedField 物件) 都支援 ConvertEmptyStringToNull 屬性,它可以決定物件在更新、插入或刪除作業時處理空字串 ("") 的方式。如果物件的 ConvertEmptyStringToNull 屬性為 true,而且該物件的值為空字串,則該物件會將 null 傳遞給資料來源做為物件值。如果物件的 ConvertEmptyStringToNull 屬性為 false,而且該物件的值為空字串,則會將空字串傳遞給資料來源做為物件值。
轉換樣板欄位中的 Null
TemplateField 物件沒有 NullDisplayText 屬性,因為樣板 (Template) 有可能包含多個繫結欄位。然而,在處理繫結欄位程序時,您可以建立自己的 null,然後利用 Eval 方法,將資料繫結值傳入具有單向資料繫結語法的程序。如果是雙向資料繫結的使用案例,您可以使用 Eval 與 Bind 方法,然後使用 DropDownList 控制項並將其 AppendDataBoundItems 屬性設為 true,如下範例所示:
<%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
<title>Northwind Employees</title>
</head>
<body>
<form id="form1" >
<div>
<asp:GridView ID="GridView1" AutoGenerateColumns="False" DataKeyNames="EmployeeID"
DataSourceID="SqlDataSource1">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID" InsertVisible="False"
ReadOnly="True" SortExpression="EmployeeID" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:TemplateField HeaderText="ReportsTo" SortExpression="ReportsTo">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" Enabled="False" DataSourceID="SqlDataSource2"
DataTextField="Name" DataValueField="EmployeeID" SelectedValue='<%# Eval("ReportsTo") %>' AppendDataBoundItems="True">
<asp:ListItem Selected="True" Value="">(none)</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" DataSourceID="SqlDataSource2"
DataTextField="Name" DataValueField="EmployeeID" SelectedValue='<%# Bind("ReportsTo") %>' AppendDataBoundItems="True">
<asp:ListItem Selected="True" Value="">(none)</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:Northwind %>"
SelectCommand="SELECT [EmployeeID], [LastName], [FirstName], [ReportsTo] FROM [Employees]"
UpdateCommand="UPDATE [Employees] SET [LastName] = @LastName, [FirstName] = @FirstName, [ReportsTo] = @ReportsTo WHERE [EmployeeID] = @EmployeeID">
<UpdateParameters>
<asp:Parameter Name="LastName" Type="String" />
<asp:Parameter Name="FirstName" Type="String" />
<asp:Parameter Name="ReportsTo" Type="Int32" />
<asp:Parameter Name="EmployeeID" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="SqlDataSource2" ConnectionString="<%$ ConnectionStrings:Northwind %>"
SelectCommand="SELECT EmployeeID, LastName + ', ' + FirstName As Name From Employees">
</asp:SqlDataSource>
</div>
</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">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
<title>Northwind Employees</title>
</head>
<body>
<form id="form1" >
<div>
<asp:GridView ID="GridView1" AutoGenerateColumns="False" DataKeyNames="EmployeeID"
DataSourceID="SqlDataSource1">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID" InsertVisible="False"
ReadOnly="True" SortExpression="EmployeeID" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:TemplateField HeaderText="ReportsTo" SortExpression="ReportsTo">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" Enabled="False" DataSourceID="SqlDataSource2"
DataTextField="Name" DataValueField="EmployeeID" SelectedValue='<%# Eval("ReportsTo") %>' AppendDataBoundItems="True">
<asp:ListItem Selected="True" Value="">(none)</asp:ListItem>
</asp:DropDownList>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" DataSourceID="SqlDataSource2"
DataTextField="Name" DataValueField="EmployeeID" SelectedValue='<%# Bind("ReportsTo") %>' AppendDataBoundItems="True">
<asp:ListItem Selected="True" Value="">(none)</asp:ListItem>
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:Northwind %>"
SelectCommand="SELECT [EmployeeID], [LastName], [FirstName], [ReportsTo] FROM [Employees]"
UpdateCommand="UPDATE [Employees] SET [LastName] = @LastName, [FirstName] = @FirstName, [ReportsTo] = @ReportsTo WHERE [EmployeeID] = @EmployeeID">
<UpdateParameters>
<asp:Parameter Name="LastName" Type="String" />
<asp:Parameter Name="FirstName" Type="String" />
<asp:Parameter Name="ReportsTo" Type="Int32" />
<asp:Parameter Name="EmployeeID" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="SqlDataSource2" ConnectionString="<%$ ConnectionStrings:Northwind %>"
SelectCommand="SELECT EmployeeID, LastName + ', ' + FirstName As Name From Employees">
</asp:SqlDataSource>
</div>
</form>
</body>
</html>
AppendDataBoundItems 屬性設為 true 時,DropDownList 控制項會同時填入靜態項目與資料來源所產生的資料。加入到 DropDownList 控制項的靜態項目具有設為空字串的 Value 屬性。包含 null 值的資料項目會利用這個屬性,繫結到靜態清單項目。
如需 Eval 和 Bind方法的詳細資訊,請參閱資料繫結運算式概觀。
使用 ObjectDataSource 控制項處理 Null 的技巧
當您建立物件做為 ObjectDataSource 控制項的來源時,可以在該物件的程式碼內管理 null 值的轉換。有兩個選項可供選擇:可為 Null 的型別 (Nullable Type) 以及強型別 (Strongly Typed) 物件 (如資料集) 的附註。
注意事項: |
---|
如需 ObjectDataSource 控制項的詳細資訊,請參閱 ObjectDataSource Web 伺服器控制項概觀。 |
使用可為 Null 的型別
當您為 ObjectDataSource 控制項建立 Select、Insert、Update 和 Delete 方法時,如果參數值在資料來源中可以為 null,則您可以將這些方法的參數和傳回值定義成可為 Null 的型別。為 Null 的型別是諸如 integer 或 Boolean 等類的實值型別 (Value Type),可以是一般值或 null 值。
如需 Visual Basic 中可為 Null 的型別之詳細資訊,請參閱可為 Null 的實值型別。如需 C# 中可為 Null 的型別之詳細資訊,請參閱使用可為 Null 的型別 (C# 程式設計手冊)。
註解強型別資料集
ObjectDataSource 控制項的通用來源物件是強型別 DataSet 物件。若要有強型別 DataSet,將資料來源傳回的 null 值轉換為所指定的值,您可以使用 nullValue 附註對 DataSet 進行註解。如需詳細資訊,請參閱為具型別的 DataSet 加上附註 (ADO.NET)。