ASP.NET2.0 ObjectDataSource的使用详解

在李万宝的博客中,对ObjectDataSource的使用进行了详细论述,收藏。。

ASP.NET2.0 ObjectDataSource的使用详解(1)
ASP.NET2.0 ObjectDataSource的使用详解(2)

<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana">本系列文章将介绍ObjectDataSource的使用,为了内容的完成性,所以虽然简单,但是还是发到首页,不知道行不行<br>本系列文章主要参考MSDN,ASP.NET快速入门和ASP.NET的文章整理而成,将由浅入深说明ObjectDataSource的使用,仅供参考,不保证内容100%的争取<br><br><br>1</span></strong></chsdate> SqlDataSourceObjectDataSource控件的比较

ASP.NET2.0提供了SqlDataSource数据源控件,后者支持用于指定连接字符串、SQL 语句或存储过程的属性,用以查询或修改数据库。但是,SqlDataSource 控件存在一个问题:该控件的缺点在于它迫使您将用户界面层与业务逻辑层混合在一起。然而随着应用程序规模的扩大,您会越来越感觉到混合多个层的做法是不可取的。 生成严格意义上的多层 Web 应用程序时,您应该具有清晰的用户界面层、业务逻辑层和数据访问层。仅仅由于 SqlDataSource 控件的强制而在用户界面层引用 SQL 语句或存储过程是不可取的。

SqlDataSourceObjectDataSource的选择,从这某中意义上说,前者适合大多数小规模的个人或业余站点,而对于较大规模的企业级应用程序,在应用程序的呈现页中直接存储 SQL 语句可能很快就会变得无法维护。这些应用程序通常需要用中间层数据访问层或业务组件构成的封装性更好的数据模型。所以使用 ObjectDataSource 控件是一种较为明智和通用的做法。

<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana">2</span></strong></chsdate> ObjectDataSource的概述

ObjectDataSource 控件对象模型类似于 SqlDataSource 控件。ObjectDataSource 公开一个 TypeName 属性(而不是 ConnectionString 属性),该属性指定要实例化来执行数据操作的对象类型(类名)。类似于 SqlDataSource 的命令属性,ObjectDataSource 控件支持诸如 SelectMethodUpdateMethodInsertMethod 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>

<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana">3</span></strong></chsdate>绑定到数据访问层

数据访问层组件封装 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);

}

也就是,通常是在业务逻辑访问层定义对数据库里记录的操作,上面就定义了GetRecordsUpdateRecordDeleteRecordInsertRecord四个方法来读取、更新、删除和插入数据库里的数据,这些方法基本上是根据SQL里的SelectUpdateDeleteInsert语句而定义。

和上面方法相对应, ObjectDataSource提供了四个属性来设置该控件引用的数据处理,可以按照如下方式关联到该类型,代码如下

<asp:ObjectDataSource TypeName="MyDataLayer" runat="server"

SelectMethod="GetRecords"

UpdateMethod="UpdateRecord"

DeleteMethod="DeleteRecord"

InsertMethod="InsertRecord"

/>

这里的SelectMethon设置为MyDataBllLayer里的GetRecords()方法,在使用时需要注意ObjectDataSource旨在以声明的方式简化数据的开发,所以这里设置SelectMethod的值为GetRecords而不是GetRecords()

同样依次类推,UpdateMethodDeleteMethodInsertMethod分别对应的是UpdateRecord

DeleteRecordInsertRecord方法。

在上面GetRecords()的定义时,读者可以看到该方法返回的类型是DataView,由于ObjectDataSource将来需要作为绑定控件的数据来源,所以它的返回类型必须如下的返回类型之一:

IenumerableDataTableDataViewDataSet或者Object

除此以外,ObjectDataSource还有一个重要的属性TypeNameObjectDataSource控件使用反射技术来从来从业务逻辑程序层的类对象调用相应的方法,所以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 [email protected],[email protected],[email protected],[email protected],[email protected] where [email protected]";

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 [email protected]";

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窗体创,使用默认的IDVisual Stduio.NET2005为我们建立业务逻辑提供了强大的支持。选中ObjectDataSource1,在其智能配置里选择配置数据源,弹出配置向导如图2-1

<shapetype id="_x0000_t75" stroked="f" filled="f" path="[email protected]@[email protected]@[email protected]@[email protected]@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype>


2-1ObjectDataSource配置向导

此时系统会枚举已经存在的类,选择ProductDAL,单击“Next”,进入“Define Data Methods”页面如图2-2。在此页面需要单独设置SelectUpdate、和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运行结果

注意:如果能够进行编辑、删除,你需要将GridViewDataKeyNames设置为数据库里的主键名。具体后面会说明。

<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False"><strong style="mso-bidi-font-weight: normal"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: Verdana">4</span></strong></chsdate>绑定到业务逻辑

在上面GetProduct的定义时,可以看到该方法返回的类型是SqlDataReader,由于ObjectDataSource将来需要作为绑定控件的数据来源,所以它的返回类型必须如下的返回类型之一:

IenumerableDataTableDataViewDataSet或者Object

为了更好的进行业务处理,我们需要更进一步的封装业务逻辑,以便返回强类型。接下来我们定义一个Product类来封装数据库,具体由Product.cs实现并放置在App_Code目录,代码如下

using System;

public class Product

{

protected int _productID;

protected String _productName;

protected int _categoryID;

protected decimal _price;

protected int _inStore;

protected String _description;

public int ProductID

{

get { return _productID; }

set { _productID = value; }

}

public String ProductName

{

get { return _productName; }

set { _productName = value; }

}

public int CategoryID

{

get { return _categoryID; }

set { _categoryID = value; }

}

public decimal Price