使用数据源控件处理 Null 数据库值
更新:2007 年 11 月
在许多情况下,当数据库表中的列中没有存储任何值时,该列返回 null。不过,在使用 ASP.NET 代码或使用数据绑定 Web 控件时,null 值可能会引发质询。例如,如果尝试将 DropDownList 控件的 SelectedValue 绑定到 null,则会引发异常。
ASP.NET 提供了一些用于处理 null 值的内置功能。如果使用内置 ASP.NET 功能并未解决该情况,还可以通过其他技术处理 null 值。
NullDisplayText 属性
可以在数据源控件(如 BoundField、CheckBoxField 和 ImageField 对象)中将绑定字段的 NullDisplayText 属性设置为用特定值(如一个字符串)替换从数据源返回的 null 值。之后,控件会将该值显示为绑定控件的文本。当在编辑操作中修改了数据绑定行时,如果绑定字段的值与 NullDisplayText 匹配(不管有没有修改该值,或用户输入了与 NullDisplayText 相同的值),该字段会将 null 作为字段值传递给数据源。如果没有设置 NullDisplayText 属性,则会将 null 值显示为空字符串 ("")。
例如,如果将 BoundField 对象的 NullDisplayText 属性设置为“(无值)”,并且绑定数据列为 null,则 BoundField 对象呈现的 Label 或 TextBox 对象的 Text 属性会设置为“(无值)”。如果用户编辑该行并将值从“(无值)”更改为“自定义值”,则会将值“自定义值”作为该字段的值传递给数据源。但是,如果绑定控件的值仍为“(无值)”,则数据控件会将 null 作为字段值传递给数据源。
ConvertEmptyStringToNull 属性
Parameter 对象、TemplateField 对象和绑定字段(BoundField、CheckBoxField、ImageField 和 AutoGeneratedField 对象)都支持 ConvertEmptyStringToNull 属性,该属性用于确定在更新、插入或删除操作中对象将如何看待空字符串 ("") 值。如果对象的 ConvertEmptyStringToNull 属性为 true,并且该对象的值是空字符串,则该对象会将 null 作为对象值传递给数据源。如果对象的 ConvertEmptyStringToNull 属性为 false,并且该对象的值是空字符串,则会将空字符串作为对象值传递给数据源。
转换模板字段中的 Null
TemplateField 对象没有 NullDisplayText 属性,因为模板可能包含多个绑定字段。不过,可以使用 Eval 方法,为绑定字段创建自己的 null 处理过程,然后将数据绑定值传递给具有单向数据绑定语法的过程。对于双向数据绑定方案,可以使用 Eval 和 Bind 方法,将 DropDownList 控件与设置为 true 的 AppendDataBoundItems 属性一起使用,如下面的示例所示。
<%@ 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 runat="server">
<title>Northwind Employees</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" 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" runat="server" 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" runat="server" 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" runat="server" 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" runat="server" 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 runat="server">
<title>Northwind Employees</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" 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" runat="server" 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" runat="server" 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" runat="server" 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" runat="server" 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 值的转换。有两个选择:可空类型和强类型对象(如数据集)的批注。
说明: |
---|
有关 ObjectDataSource 控件的更多信息,请参见 ObjectDataSource Web 服务器控件概述。 |
使用可空类型
当为 ObjectDataSource 控件创建源对象的选择、插入、更新和删除方法时,如果参数值在数据源中可以是 null,则可以将这些方法的参数和返回值定义为可空类型。可空类型指可为普通值或 null 值的值类型,如整数或布尔值。
有关在 Visual Basic 中使用可以为 null 的类型的信息,请参见可以为 Null 的值类型。有关在 C# 中使用可空类型的信息,请参见使用可空类型(C# 编程指南)。
为强类型数据集加注批注
ObjectDataSource 控件的公共源对象是强类型 DataSet 对象。若要让强类型 DataSet 将从数据源返回的 null 值转换为您指定的值,可以使用 nullValue 批注来为强类型 DataSet 加注批注。有关更多信息,请参见批注类型化数据集 (ADO.NET)。