通过使用 ObjectDataSource 将业务对象绑定到 GridView 以填充自定义业务对象,ASP.NET 2.0






4.30/5 (17投票s)
2006年1月20日
3分钟阅读

114642

1275
一篇完整的文章,介绍如何使用通用方法填充自定义业务对象,将这些对象绑定到使用 ObjectDataSource 控件的 GridView。
引言
本文解释了如何加载自定义业务对象并将它们绑定到 GridView
。只需要一个通用方法来加载所有业务对象。我使用一个简单的属性类来将数据从数据库字段映射到对象属性。业务对象的容器是一个泛型列表。目前,我想保持简单。将来,我想扩展功能并使其更具可扩展性。此项目使用 .NET 2.0 中的以下新功能
- 从
DataReader
加载DataTable
。 - 从 web.config 获取
ConnectionString
部分。 - 泛型。
ObjectDataSource
控件。
解决方案演练
此解决方案包含两个项目。第一个项目(类库)解释了如何从数据库记录填充自定义业务对象。第二个项目(网站)解释了如何使用 ObjectDataSource
控件将自定义业务对象绑定到 GridView
。出于演示目的,我使用了 SQL 2005 附带的“AdventureWorks”数据库。
填充自定义业务对象(项目:AWBusinessObjects)
此项目包含一个数据库帮助类、一个自定义属性类、一个业务对象基类和两个示例业务对象。
数据库帮助类:DBHelper.cs
它用于使用 DataReader
将数据从数据库加载到断开连接的 DataTable
。此功能在 .NET 2.0 中引入。System.Configuration
的 ConfigurationManager
用于从 web.config 文件获取数据库连接信息。
class DBHelper
{
private string strConn;
private SqlCommand dbCmd;
private SqlConnection dbConn;
private SqlDataReader dbReader;
private DataTable dbTable;
//Constructor
public DBHelper()
{
ConnectionStringSettings settings =
ConfigurationManager.ConnectionStrings["DBConn"];
if (settings != null)
{
strConn = settings.ConnectionString;
}
}
//Retrieve Data
public DataTable RetrieveTable(string pSqlText)
{
try
{
dbTable = new DataTable();
dbConn = new SqlConnection(strConn);
dbCmd = dbConn.CreateCommand();
dbCmd.CommandText = pSqlText;
dbConn.Open();
dbReader = dbCmd.ExecuteReader();
if (dbReader != null && dbReader.HasRows)
{
dbTable.Load(dbReader);
}
}
finally
{
dbConn.Close();
}
return dbTable;
}
}
属性类:MapInfo.cs
它定义了将数据从数据库字段映射到业务对象属性的信息。这里没什么特别的。它包含两个字段。此属性可以在类级别、属性级别或字段级别使用。AllowMultiple
控制属性是否为多用途。
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Property |
AttributeTargets.Field,AllowMultiple=true)]
class MapInfo: System.Attribute
{
private string dbFieldName;
private string objPropertyName;
public MapInfo(string pDBFieldName,
string pObjPropertyName)
{
dbFieldName = pDBFieldName;
objPropertyName = pObjPropertyName;
}
public string DBFieldName
{
get { return dbFieldName;}
}
public string ObjPropertyName
{
get { return objPropertyName;}
}
}
业务对象基类:AWBase.cs
这包含用于填充继承的业务对象的通用方法。此处使用反射来获取自定义属性和属性。它遍历 DataTable
中的所有行,并使用自定义属性数组设置属性值。泛型列表的基类类型用作业务对象的容器。如果数据库值为 DBNull
,则使用 null
作为属性值。
public abstract class AWBase
{
protected string SqlSelectString;
protected Type BusObjectType;
protected List<AWBase> LoadData()
{
List<AWBase> _list = new List<AWBase>();
DBHelper dbHelper = new DBHelper();
//Get Data
DataTable dtBusinessObject =
dbHelper.RetrieveTable(SqlSelectString);
//Custom Attributes
object[] attributes =
BusObjectType.GetCustomAttributes(typeof(MapInfo), false);
//Loop through all records in Table
if (dtBusinessObject != null && dtBusinessObject.Rows.Count > 1)
{
for (int introw = 0; introw <
dtBusinessObject.Rows.Count; introw++)
{
AWBase busObject =
(AWBase)Activator.CreateInstance(BusObjectType);
//loop through all custom attributes
for (int i = 0; i < attributes.Length; i++)
{
MapInfo mapinfo = (MapInfo)attributes[i];
object DBValue =
dtBusinessObject.Rows[introw][mapinfo.DBFieldName];
PropertyInfo pinfo =
BusObjectType.GetProperty(mapinfo.ObjPropertyName);
pinfo.SetValue(busObject, DBValue.GetType()
== typeof(DBNull) ? null: DBValue, null);
}
_list.Add(busObject);
}
}
return _list;
}
}
业务对象:Product.cs
它是业务对象的示例类。此类将从“Production.Product”表填充。它具有映射信息和公共属性。“GetProducts
”方法返回产品的泛型列表。稍后,此方法用作 ObjectDataSource
控件中的 SelectMethod
。为了将基类转换为子类,使用了泛型 ConvertAll
函数。通常,所有业务对象都包含映射信息、公共属性、一个选择方法和一个显式强制转换方法
//Mapping Information
[MapInfo("ProductID", "ID")]
[MapInfo("Name", "Name")]
[MapInfo("ProductNumber", "Code")]
public class Product : AWBase
{
private int id;
private string name;
private string code;
...
//Properties
public int ID
{
get { return id; }
set { id = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Code
{
get { return code; }
set { code = value; }
}
....
//explict casting
public Product AWBaseToProduct(AWBase pAWBase)
{
return (Product)pAWBase;
}
//Get Products
public List<Product> GetProducts()
{
base.SqlSelectString =
"select * from Production.Product";
base.BusObjectType = this.GetType();
List<AWBase> list = base.LoadData();
return list.ConvertAll<Product>(new
Converter<AWBase,Product>(AWBaseToProduct));
}
}
Contact
业务对象中的“GetContacts
”方法将如下所示
public List<Contact> GetContacts()
{
base.SqlSelectString = "select * from Person.Contact";
base.BusObjectType = this.GetType();
List<AWBase> list = base.LoadData();
return list.ConvertAll<Contact>(new
Converter<AWBase,Contact>(AWBaseToContact));
}
将业务对象的泛型列表绑定到 GridView(项目:AWDemo)
这里不需要编写代码。只需拖动和配置控件即可。我在这里给出了步骤顺序
- 创建一个新的网站。
- 添加对先前创建的项目的引用。
- 将“
ObjectDataSource
”控件拖到网页上。 - 从数据源配置向导中选择
TypeName
和SelectMethod
。 - 将“
GridView
”控件拖到网页上。 - 设置
DataSourceID
。 - 配置分页属性和
GridView
字段。
aspx 页面中的代码如下所示
<asp:GridView id="GridView1" runat="server"
CellPadding="4" GridLines="None" ForeColor="#333333"
DataSourceID="ObjectDataSource1"
AutoGenerateColumns="False" AllowPaging="True"
PageSize="20" AllowSorting="True"
EmptyDataText="No Products Found">
<FooterStyle BackColor="#1C5E55"
Font-Bold="True" ForeColor="White" />
<Columns>
<asp:BoundField DataField="ID"
HeaderText="ID" ></asp:BoundField>
<asp:BoundField DataField="Name"
HeaderText="Name" ></asp:BoundField>
<asp:BoundField DataField="Code"
HeaderText="Code" ></asp:BoundField>
<asp:CheckBoxField DataField="Finished"
HeaderText="Finished" ></asp:CheckBoxField>
<asp:BoundField DataField="Size"
HeaderText="Size" NullDisplayText="N/A">
</asp:BoundField>
<asp:BoundField DataField="Cost"
HeaderText="Cost" NullDisplayText="N/A">
</asp:BoundField>
<asp:BoundField DataField="Color"
HeaderText="Color" NullDisplayText="N/A">
</asp:BoundField>
<asp:BoundField DataField="ModifiedDate"
HeaderText="ModifiedDate">
</asp:BoundField>
</Columns>
<RowStyle BackColor="#E3EAEB" />
<EditRowStyle BackColor="#7C6F57" />
<SelectedRowStyle BackColor="#C5BBAF"
Font-Bold="True" ForeColor="#333333" />
<PagerStyle BackColor="#666666"
ForeColor="White" HorizontalAlign="Center" />
<HeaderStyle BackColor="#1C5E55"
Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource1"
runat="server" SelectMethod="GetProducts"
TypeName="Product"></asp:ObjectDataSource>
我希望我保持了简单,希望您会觉得它有用。