1 SqlDataSource 和 ObjectDataSource 控件的比较
ASP.NET2.0提供了 SqlDataSource 数据源控件,后者支持用于指定连接字符串、 SQL 语句或存储过程的属性,用以查询或修改数据库。但是, SqlDataSource 控件存在一个问题:该控件的缺点在于它迫使您将用户界面层与业务逻辑层混合在一起。然而随着应用程序规模的扩大,您会越来越感觉到混合多个层的做法是不可取的。 生成严格意义上的多层 Web 应用程序时,您应该具有清晰的用户界面层、业务逻辑层和数据访问层。仅仅由于 SqlDataSource 控件的强制而在用户界面层引用 SQL 语句或存储过程是不可取的。
SqlDataSource 和 ObjectDataSource 的选择,从这某中意义上说,前者适合大多数小规模的个人或业余站点,而对于较大规模的企业级应用程序,在应用程序的呈现页中直接存储 SQL 语句可能很快就会变得无法维护。这些应用程序通常需要用中间层数据访问层或业务组件构成的封装性更好的数据模型。所以使用 ObjectDataSource 控件是一种较为明智和通用的做法。
2 ObjectDataSource 的概述
ObjectDataSource 控件对象模型类似于 SqlDataSource 控件。 ObjectDataSource 公开一个 TypeName 属性(而不是 ConnectionString 属性),该属性指定要实例化来执行数据操作的对象类型(类名)。类似于 SqlDataSource 的命令属性, ObjectDataSource 控件支持诸如 SelectMethod 、 UpdateMethod 、 InsertMethod 和 DeleteMethod 的属性,用于指定要调用来执行这些数据操作的关联类型的方法。本节介绍一些方法,用于构建数据访问层和业务逻辑层组件并通过 ObjectDataSource 控件公开这些组件。 下面是该控件的声明方式:
<asp:ObjectDataSource
CacheDuration="string|Infinite" CacheExpirationPolicy="Absolute|Sliding"
CacheKeyDependency="string"
ConflictDetection="OverwriteChanges|CompareAllValues"
ConvertNullToDBNull="True|False" DataObjectTypeName="string"
DeleteMethod="string" EnableCaching="True|False"
EnablePaging="True|False" EnableTheming="True|False"
EnableViewState="True|False" FilterExpression="string"
ID="string" InsertMethod="string"
MaximumRowsParameterName="string"
OldValuesParameterFormatString="string"
OnDataBinding="DataBinding event handler"
OnDeleted="Deleted event handler" OnDeleting="Deleting event handler"
OnDisposed="Disposed event handler" OnFiltering="Filtering event handler"
OnInit="Init event handler" OnInserted="Inserted event handler"
OnInserting="Inserting event handler" OnLoad="Load event handler"
OnObjectCreated="ObjectCreated event handler"
OnObjectCreating="ObjectCreating event handler"
OnObjectDisposing="ObjectDisposing event handler"
OnPreRender="PreRender event handler" OnSelected="Selected event handler"
OnSelecting="Selecting event handler" OnUnload="Unload event handler"
OnUpdated="Updated event handler" OnUpdating="Updating event handler"
runat="server" SelectCountMethod="string"
SelectMethod="string" SortParameterName="string"
SqlCacheDependency="string" StartRowIndexParameterName="string"
TypeName="string" UpdateMethod="string"
>
<DeleteParameters>
<asp:ControlParameter ControlID="string"
ConvertEmptyStringToNull="True|False"
DefaultValue="string"
Direction="Input|Output|InputOutput|ReturnValue"
Name="string"
PropertyName="string"
Size="integer"
Type="Empty|Object|DBNull|Boolean|Char|SByte|
Byte|Int16|UInt16|Int32|UInt32|Int64|UInt64|
Single|Double|Decimal|DateTime|String"
/>
<asp:CookieParameter CookieName="string" />
<asp:FormParameter FormField="string" />
<asp:Parameter Name="string" />
<asp:ProfileParameter PropertyName="string" />
<asp:QueryStringParameter QueryStringField="string" />
<asp:SessionParameter SessionField="string" />
</DeleteParameters>
<FilterParameters>... ...</FilterParameters>
<InsertParameters>... ...</InsertParameters>
<SelectParameters>... ...</SelectParameters>
<UpdateParameters>... ...</UpdateParameters>
</asp:ObjectDataSource>
3 绑定到数据访问层
数据访问层组件封装 ADO.NET 代码以通过 SQL 命令查询和修改数据库。它通常提炼创建 ADO.NET 连接和命令的详细信息,并通过可使用适当的参数调用的方法公开这些详细信息。典型的数据访问层组件可按如下方式公开:
public class MyDataBllLayer {
public DataView GetRecords();
public int UpdateRecord(int recordID, String recordData);
public int DeleteRecord(int recordID);
public int InsertRecord(int recordID, String recordData);
}
也就是 , 通常是在业务逻辑访问层定义对数据库里记录的操作,上面就定义了 GetRecords 、 UpdateRecord 、 DeleteRecord 和 InsertRecord 四个方法来读取、更新、删除和插入数据库里的数据,这些方法基本上是根据 SQL 里的 Select 、 Update 、 Delete 和 Insert 语句而定义。
和上面方法相对应, ObjectDataSource 提供了四个属性来设置该控件引用的数据处理,可以按照如下方式关联到该类型,代码如下
<asp:ObjectDataSource TypeName="MyDataLayer" runat="server"
SelectMethod="GetRecords"
UpdateMethod="UpdateRecord"
DeleteMethod="DeleteRecord"
InsertMethod="InsertRecord"
/>
这里的 SelectMethon 设置为 MyDataBllLayer 里的 GetRecords() 方法,在使用时需要注意 ObjectDataSource 旨在以声明的方式简化数据的开发,所以这里设置 SelectMethod 的值为 GetRecords 而不是 GetRecords() 。
同样依次类推, UpdateMethod 、 DeleteMethod 、 InsertMethod 分别对应的是 UpdateRecord
、 DeleteRecord 、 InsertRecord 方法。
在上面 GetRecords ()的定义时,读者可以看到该方法返回的类型是 DataView ,由于 ObjectDataSource 将来需要作为绑定控件的数据来源,所以它的返回类型必须如下的返回类型之一:
Ienumerable 、 DataTable 、 DataView 、 DataSet 或者 Object 。
除此以外, ObjectDataSource 还有一个重要的属性 TypeName , ObjectDataSource 控件使用反射技术来从来从业务逻辑程序层的类对象调用相应的方法,所以 TypeName 的属性值就是用来标识该控件工作时使用的类名称,下面通过 Simple_ObjectDataSource.aspx 来说明 ObjectDataSource 的基本使用。
1 )建立数据业务逻辑层
为了方装业务逻辑我建立了 ProductDAL.cs 文件。在该文件里定义了 GetProduct 方法获取产品列表, UpdateProduct 方法更新产品记录, DeleteProduct 删除产品记录,为了便于共享,将该文件放置在 App_Code 目录下,完整代码如1 -1 :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Web;
/// <summary>
/// Summary description for ProductBLL
/// </summary>
public class ProductDAL
{
protected int _count = -1;
public ProductDAL()
{ }
string _connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
public SqlDataReader GetProduct()
{
SqlConnection con = new SqlConnection(_connectionString);
string selectString = "SELECT * FROM Products";
SqlCommand cmd = new SqlCommand(selectString, con);
con.Open();
SqlDataReader dtr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
return dtr;
}
public void UpdateProduct(int productID, string productName, int categoryID, decimal price, Int16 inStore,string description)
{
SqlConnection con = new SqlConnection(_connectionString);
string updateString = "UPDATE Products set ProductName=@ProductName,CategoryID=@CategoryID,Price=@Price,InStore=@InStore,Description=@Description where ProductID=@ProductID";
SqlCommand cmd = new SqlCommand(updateString, con);
cmd.Parameters.AddWithValue("@ProductID",productID);
cmd.Parameters.AddWithValue("@ProductName",productName);
cmd.Parameters.AddWithValue("@CategoryID",categoryID);
cmd.Parameters.AddWithValue("@Price",price);
cmd.Parameters.AddWithValue("@InStore",inStore);
cmd.Parameters.AddWithValue("@Description",description);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
public void DeleteProduct(int ProductId)
{
SqlConnection con = new SqlConnection(_connectionString);
string deleteString = "DELETE FROM Products WHERE ProductID=@ProductID";
SqlCommand cmd = new SqlCommand(deleteString, con);
cmd.Parameters.AddWithValue("@ProductID", ProductId);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
代码1 -1 ProductDAL.cs 源文件
2 )建立表示层
建立一个页面 Simple_ObjectDataSource.aspx 然后将 ObjectDataSource 控件托方到 Web 窗体创,使用默认的 ID 。 Visual Stduio.NET2005 为我们建立业务逻辑提供了强大的支持。选中 ObjectDataSource1 ,在其智能配置里选择配置数据源,弹出配置向导如图 2-1 。
图 2-1ObjectDataSource 配置向导
此时系统会枚举已经存在的类,选择 ProductDAL ,单击“ Next ”,进入“ Define Data Methods ”页面如图 2-2 。在此页面需要单独设置 Select 、 Update 、和 Delete 分别如下图
2-30 设置 Select 属性对应的方法 GetProduct
2-31 设置 Update 属性对应的方法 UpdateProduct
图 2-32 设置 Delete 属性对应的方法 DeleteProduct
通过上面的设置系统自动生成如下代码如下
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DeleteMethod="DeleteProduct"
SelectMethod="GetProduct" TypeName="ProductDAL" UpdateMethod="UpdateProduct">
<DeleteParameters>
<asp:Parameter Name="ProductId" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="productID" Type="Int32" />
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="categoryID" Type="Int32" />
<asp:Parameter Name="price" Type="Decimal" />
<asp:Parameter Name="inStore" Type="Int16" />
<asp:Parameter Name="description" Type="String" />
</UpdateParameters>
</asp:ObjectDataSource>
代码 2-11 Simple_ObjectDataSource.aspx 部分源代码
图 2-33 显示了运行结果,此时我们可以编辑或者删除现有的产品记录。
图 2-33 Simple_ObjectDataSource.aspx 运行结果
注意 : 如果能够进行编辑、删除,你需要将 GridView 的 DataKeyNames 设置为数据库里的主键名。具体后面会说明。