摘要:ADO.NET 和 SqlDataSource 使得人们可以很容易地访问 ASP.NET 2.0 中的两层数据。但是,它们在 n 层应用程序中就不是那么有效了,而 ObjectDataSource 却能在 n 层应用程序中为业务对象提供相同的易用性。学习如何使用 ASP.NET 2.0 Framework 并利用 ObjectDataSource 控件生成严格意义上的多层 Web 应用程序。

简介

在 Microsoft ASP.NET 2.0 Framework 中,数据库访问得到了极大的简化。利用全新的 SqlDataSource 控件,您无需编写一行代码就可以选择、更新、插入和删除数据库数据。

生成简单的应用程序时,SqlDataSource 控件是一个很好的选择。如果您需要迅速生成一个使用户可以显示和编辑数据库记录的 Web 页,使用 SqlDataSource 控件在几分钟之内就能完成此工作。

例如,我自己就曾计时生成了这么一个页面。通过结合使用 SqlDataSource 控件与 GridView 控件,我在 1 分 15秒 内就能生成一个用于显示 Northwind Products 数据库表的内容的页面。就有这么快!

但是,SqlDataSource 控件存在一个问题。如果您使用 SqlDataSource 控件,那您就是在做不太妙的事情。SqlDataSource 控件的缺点在于它迫使您将用户界面层与业务逻辑层混合在一起。任何应用程序架构师都会告诉您:混合多个层的行为是不可取的。

生成严格意义上的多层 Web 应用程序时,您应该具有清晰的用户界面层、业务逻辑层和数据访问层。仅仅由于 SqlDataSource 控件的强制而在用户界面层引用 SQL 语句或存储过程是完全错误的。

那么为什么您要关心这些东西呢?不错,在很多情况下,您不必在意。如果您正在创建一个简单的 Web 应用程序,完全可以使用 SqlDataSource 控件。例如,如果您需要生成一个由单独页面组成的应用程序来显示数据库的表的内容,那么将应用程序划分为多个应用程序层就很不明智。

遗憾的是(如果您已经为此“交过学费”,则会感到幸运),并非所有的 Web 应用程序都很简单。应用程序达到一定的复杂程度之后,如果将其划分为多个应用程序层,则生成和维护它们就更轻松。

将应用程序划分为多个应用程序层有很多优点。如果您有一个清晰的业务逻辑层,就能够创建一个可以从多个页面调用的方法库。换句话说,创建一个清晰的业务逻辑层提升了代码重用。此外,创建清晰而独立的应用程序层使得应用程序更易于修改。例如,清晰的层次使您无需修改数据访问代码就可以修改用户界面。

如果您需要使用 ASP.NET Framework 生成多层 Web 应用程序,那么您可以使用 ASP.NET 2.0 Framework 所引入的另一个新控件:ObjectDataSource 控件ObjectDataSource 控件使您可将诸如 GridViewDropDownList 这样的用户界面控件绑定到一个中间层组件。

这篇文章的主题就是 ObjectDataSource 控件。在这篇文章中,您将学习如何使用此控件来显示和编辑数据库数据。我们还将讨论如何结合使用 ObjectDataSource 控件和 SqlDataSource 控件以简化数据库访问。

使用 ObjectDataSource 控件编辑数据

ObjectDataSource 控件包含 4 个重要属性:SelectMethod 属性、UpdateMethod 属性、InsertMethod 属性和 DeleteMethod 属性。综合利用这些属性,您能够指定执行标准数据库操作所需的所有方法。
例子:
绑定到数据访问层
    数据访问层组件封装 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的属性值就是用来标识该控件工作时使用的类名称,下面的例子演示了ObjectDataSource的基本使用。

在该例子里定义了一个数据业务逻辑层来处理数据库链接和业务逻辑,这些处理都是有App_Code文件夹下的NorthwndDB.cs文件完成,先大致浏览一下该文件里定义的方法:

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;
public class EmployeeInfo
    {
        private string _connectionString;

public  EmployeeInfo()
        {      _connectionString =
        ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
        }

public   SqlDataReader GetEmployees()
        {
            SqlConnection con = new SqlConnection(_connectionString);
            string selectString = "SELECT EmployeeID,LastName,Firstname,Title,Address,City,Region,PostalCode  FROM Employees ORDER BY EmployeeID";
            SqlCommand cmd = new SqlCommand(selectString, con);
            con.Open();
            SqlDataReader dtr =
              cmd.ExecuteReader(CommandBehavior.CloseConnection);
            return dtr;
        }

public void UpdateEmployee(int EmployeeId, string LastName, string Firstname, string Title, string Address, string City, String Region, string PostalCode)
        {
            SqlConnection con = new SqlConnection(_connectionString);
            string updateString = "UPDATE Employees SET Address=@Address,City=@City WHERE EmployeeID=@EmployeeID";
            SqlCommand cmd = new SqlCommand(updateString, con);
            cmd.Parameters.AddWithValue("@Address", Address);
            cmd.Parameters.AddWithValue("@City", City);
            cmd.Parameters.AddWithValue("@EmployeeID", EmployeeId);
            con.Open();
            cmd.ExecuteNonQuery();
            con.Close();
        }

public   void DeleteEmployee(int EmployeeId)
        {
            SqlConnection con = new SqlConnection(_connectionString);
            string deleteString = "DELETE Employees  WHERE EmployeeID=@EmployeeID";
            SqlCommand cmd = new SqlCommand(deleteString, con);
            cmd.Parameters.AddWithValue("@EmployeeId", EmployeeId);
            con.Open();
            cmd.ExecuteNonQuery();
            con.Close();
        }
    }

在这段代码里,定义了GetEmployees方法来获取所有员工级别信息,UpdateEmployee方法更新员工的基本资料,DeleteEmployee方法用来删除员工资料,这样就可以在ObjectDataSource1.aspx里使用如下代码调用业务逻辑的处理,如下
<asp:GridView
        ID="GridView1"
        DataSourceID="ObjectDataSource1"
        DataKeyNames="EmployeeId"
        AutoGenerateColumns="true"
        AutoGenerateEditButton="True"
        AutoGenerateDeleteButton="True"
        Runat="Server" CellPadding="4" Font-Names="Verdana" Font-Size="X-Small" ForeColor="#333333" GridLines="None">
           … …
     </asp:GridView>  
       
     <asp:ObjectDataSource
        ID="ObjectDataSource1"
        TypeName="EmployeeInfo"
        SelectMethod="GetEmployees"
        UpdateMethod="UpdateEmployee"       
        DeleteMethod="DeleteEmployee"
        Runat="Server">
       
        <UpdateParameters>
            <asp:Parameter     Name="EmployeeId"       Type="Int32" />
            <asp:Parameter     Name="Address" />
            <asp:Parameter    Name="City"    />
        </UpdateParameters>
     </asp:ObjectDataSource>

上面使用了GrieView控件后面会有专门介绍,这里我们专注ObjectDataSource控件的使用,在该控件里设置   TypeName为"EmployeeInfo"表示将来调用的类名称为EmployeeInfo,调用SelectMethond/UpdateMethod/DeleteMethod调用的的方法分别是EmployeeInfo类里的GetEmployees/UpdateEmployee/DeleteEmployee方法。
   具体运行可以自己试验。从运行结果里单击“Edit”可以更新员工的资料,单击“Delete”将删除员工的资料。

在运行上面的例子里,可能看到UpdateEmployee的定义如下:
       public void UpdateEmployee(int EmployeeId, string LastName, string Firstname, string Title, string Address, string City, String Region, string PostalCode)
        {     ... ...
            cmd.Parameters.AddWithValue("@Address", Address);
            cmd.Parameters.AddWithValue("@City", City);
            cmd.Parameters.AddWithValue("@EmployeeID", EmployeeId);
            ... ...
        }

这段代码表示更新员工资料时,其实只更新了员工的地址(Address)和所在的程序(City),而对于姓名(FirstName,LastName)、职称(Title)等并没有更新。
    既然FistName、LastName、Title等并没有更新,为什么不将UpdateEmployee写成如下方式呢?
   public void UpdateEmployee(int EmployeeId string Address, string City,)
        {     ... ...
            cmd.Parameters.AddWithValue("@Address", Address);
            cmd.Parameters.AddWithValue("@City", City);
            cmd.Parameters.AddWithValue("@EmployeeID", EmployeeId);
            ... ...
        }
   也就是只保留需要的三个参数而将其它变量不写,如果这样做将发生错误如下:
 
提示错误为:ObjectDataSource1找不到一个包含Address,City,LastName,Firstname,Title,Region,PostalCode和Employee参数的非泛型方法(具体原因我还没有进行验证,我的感觉是ObjectDataSource是根据Select语句自动生成Delete/Insert/Update等的,所以在更新时,同样需要该参数,你可以到如下MSDN查看SelectMethod的说明:
http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.objectdatasource.selectmethod(VS.80).aspx

)。
而我看到的例子,大多都是如下写法:
     
   public void UpdateEmployee(int EmployeeId, string LastName, string Firstname, string Title, string Address, string City, String Region, string PostalCode)
        {
     UpdateEmployee(EmployeeId,Address,City)
        }

public void UpdateEmployee(int EmployeeId,   string Address, string City )
        {
            SqlConnection con = new SqlConnection(_connectionString);
            string updateString = "UPDATE Employees SET Address=@Address,City=@City WHERE EmployeeID=@EmployeeID";
            SqlCommand cmd = new SqlCommand(updateString, con);
            cmd.Parameters.AddWithValue("@Address", Address);
            cmd.Parameters.AddWithValue("@City", City);
            cmd.Parameters.AddWithValue("@EmployeeID", EmployeeId);
            con.Open();
            cmd.ExecuteNonQuery();
            con.Close();
        }
通过重载UpdateEmployee方法,便于数据的扩展和维护。

绑定到业务逻辑

为了更好的进行业务处理,需要进一步封装业务逻辑,以便返回强类型,举例定义一个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
    {
        get { return _price; }
        set { _price = value; }
    }

public int InStore
    {
        get { return _inStore; }
        set { _inStore = value; }
    }
    public String Description
    {
        get { return _description; }
        set { _description = value; }
    }

public Product()
    { }

public Product(int productID, string productName, int categoryID, decimal price, int instore, string description)
    {
        this._productID = productID;
        this._productName = productName;
        this._categoryID = categoryID;
        this._price = price;
        this._inStore = instore;
        this._description = description;
    }

}

然后定义业务逻辑类ProductDB.cs来进行处理:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using System.Data.SqlClient;

/// <summary>
/// ProductDB 的摘要说明
/// </summary>
public class ProductDB
{
 public ProductDB()
 {
  //
  // TODO: 在此处添加构造函数逻辑
  //
 }

public List<Product> GetProduct()
    {
        List<Product> products = new List<Product>();

SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString);

string commandText = "select * from Products";

SqlCommand command = new SqlCommand(commandText,conn);

conn.Open();

SqlDataReader dr = command.ExecuteReader();

while (dr.Read())
        {
            Product prod = new Product();

prod.ProductID = (int)dr["ProductID"];
            prod.ProductName = (string)dr["ProductName"];
            prod.CategoryID = (int)dr["CategoryID"];
            prod.Price = (decimal)dr["price"];
            prod.InStore = (Int16)dr["InStore"];
            prod.Description = (String)dr["Description"];

products.Add(prod);
        }

dr.Close();
        conn.Close();

return products;

}

public void UpdateProduct(Product pro)
    {
        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString);
        SqlCommand updatecmd = new SqlCommand("UPDATE Products set ProductName=@ProductName,CategoryID=@CategoryID,Price=@Price,InStore=@InStore,Description=@Description where ProductID=@ProductID", conn);
        updatecmd.Parameters.Add(new SqlParameter("@ProductName", pro.ProductName));
        updatecmd.Parameters.Add(new SqlParameter("CategoryID", pro.CategoryID));
        updatecmd.Parameters.Add(new SqlParameter("@Price", pro.Price));
        updatecmd.Parameters.Add(new SqlParameter("@InStore", pro.InStore));
        updatecmd.Parameters.Add(new SqlParameter("@Description", pro.Description));
        updatecmd.Parameters.Add(new SqlParameter("@ProductID", pro.ProductID));
        conn.Open();
        updatecmd.ExecuteNonQuery();
        conn.Close();

}

public void DeleteProduct(Product pro)
    {

SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString);
        SqlCommand delcmd = new SqlCommand("delete from Products where ProductID=@ProductID", conn);
        delcmd.Parameters.Add(new SqlParameter("@ProductID", pro.ProductID));
        conn.Open();
        delcmd.ExecuteNonQuery();
        conn.Close();
    }

}

最后建立前台页面文件,添加objectdatasource控件显示数据
 <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DataObjectTypeName="Product"
            DeleteMethod="DeleteProduct" SelectMethod="GetProduct" TypeName="ProductDB" UpdateMethod="UpdateProduct">
        </asp:ObjectDataSource>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateDeleteButton="True" AutoGenerateEditButton="True"
            CellPadding="4" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" Font-Names="Verdana"
            Font-Size="XX-Small" ForeColor="#333333" GridLines="None">
            <FooterStyle BackColor="#1C5E55" Font-Bold="True" ForeColor="White" />
            <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>

转载于:https://www.cnblogs.com/zgqys1980/archive/2007/07/24/829171.html

使用 ASP.NET 2.0 ObjectDataSource 控件(整理自msdn)相关推荐

  1. 动手做ASP.NET 2.0服务器端控件——AutoCheckTreeView(二)接口设计

    感谢谭振林先生所著<道不远人--深入解析ASP.NET 2.0控件开发> 讨论完了功能,我们来思考一下这个控件应该怎么设计. 1,给控件取个名字吧,因为一开始小凡只是考虑了自动勾选功能,所 ...

  2. ASP.Net2.0 数据绑定控件的优越性在哪里?

    尽管有丰富.功能强大的编程接口,ASP.NET 1.x DataGrid 控件仍需要编写大量自定义代码来处理普通操作,如分页.排序.编辑和删除数据.例如,当用户单击以保存或取消更改时,DataGrid ...

  3. ASP.NET2.0 分页控件 PagerPro.dll (1.1.0 最新)

    快来瞧,快来看了啊,新出炉的ASP.NET分页控件,热乎啦! 最新的ASP.NET2.0分页控件,经过对样式的处理,现有None和Standard两种样式,可以自定义是否显示Page Count 和 ...

  4. 【开源】QuickPager ASP.NET2.0分页控件V2.0.0.3 【增加了使用说明】

    ================================ 欢迎转载,但是请注明出处.本文出自博客园 .谢谢合作! ================================ 最新版本:V ...

  5. 利用ASP.NET2.0向导控件一步步建立与用户的交互--------提高和自定义用户体验

    本文是利用ASP.NET2.0向导控件一步步建立与用户的交互--------基本概念的后续文章,介绍了Wizard控件的高级使用以提高用户使用体验. 单击下面链接进行查看 http://www.cnm ...

  6. 【开源】我的分页控件正式命名为QuickPager ASP.NET2.0分页控件

    分页控件正式命名为 QuickPager ASP.NET2.0分页控件 . 版本号:2.0.0.1 Framework:.net2.0 分页方式:PostBack .URL (暂时没有实现URL的分页 ...

  7. ObjectDataSource控件的使用...

    --------------------------------------------------------------------------- [System.ComponentModel.D ...

  8. [原创]ASP.net 2.0 ObjectDataSource 应用操作代码实例(1)-—访问SQL2005

    ObjectDataSource是比较有意思的一个东西 通过在网络上遍访各位高手,终于自己有了一些心得体会.现总结如下: 1.ObjectDataSource的作用是给页面的数据展示控件提供数据 2. ...

  9. ASP.NET中 Calendar(日期控件)的使用

    ylbtech-ASP.NET-Control-Basic:Calendar(日期控件)的使用 ASP.NET中 Calendar(日期控件)的使用. 1.A,运行效果返回顶部 Calendar(日期 ...

  10. ASP.Net服务端基本控件介绍

    lASP.Net服务端控件是ASP.Net对HTML的封装,在C#代码中就可以用txt1.Text='abc'这种方式来修改input的值,ASP.Net会将服务端控件转成HTML代码输出给浏览器.服 ...

最新文章

  1. RuntimeError: Expected object of device type cuda but got device type cpu for argument pytorch数据位置
  2. Parallels Desktop 重装系统
  3. 贷款总是被拒,到底是什么原因?
  4. 使用vivado进行逻辑开发时,进行到Generate Bitstream时报错
  5. java java.lang.enum_源码阅读-java基础-java.lang.Enum
  6. java复习系列[6] - Java集合
  7. IDEA+Maven:cannot download sources
  8. matlab拉格朗日曲线_数学中高耸的金字塔——拉格朗日
  9. java adt官网下载_android adt下载
  10. 个人邮箱地址格式,如何能够正确的书写?
  11. 瑞吉外卖_短信验证bug
  12. 新手设计师必须知道的4大设计软件
  13. php只取时间的下士_php取当时的年月日时分秒毫秒
  14. 算算我们80后的小孩今后读大学要花多少钱
  15. Matlab ——旋转矩阵,四元数,欧拉角之间的转换
  16. linux 流量 脚本,实时查看linux网卡流量脚本
  17. 规范你的代码编写风格
  18. 学计算机惠普和联想笔记本哪个好,笔记本做得好,未必只有惠普和联想
  19. 上海车艺尚教你如何DIY原厂8.8寸大屏幕----宝马车友必看
  20. Apple Store 亮相中国

热门文章

  1. jQuery设置文本框回车事件
  2. 29. 数组中出现超过一半的数字(C++版本)
  3. 15. (附加)链表中间节点(C++版本)
  4. maven全局配置文件settings.xml详解
  5. android的简单知识,Android基础知识(简单实例计算器)
  6. js 延迟几秒执行_息息相关的 JS 同步,异步和事件轮询
  7. cmd后台运行exe_了解运行命令的原理,为QQ制作运行命令启动
  8. (秒杀项目) 4.5 项目部署与压测
  9. java砖头铺路面试题,Java基础知识面试题
  10. windows应用x64和x86运行效率_现在你可以在 Windows 中运行 Linux 应用了 | Linux 中国...