65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.30/5 (17投票s)

2006年1月20日

3分钟阅读

viewsIcon

114642

downloadIcon

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.ConfigurationConfigurationManager 用于从 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”控件拖到网页上。
  • 从数据源配置向导中选择 TypeNameSelectMethod
  • 将“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>

我希望我保持了简单,希望您会觉得它有用。

© . All rights reserved.