代码改变世界

ADO.NET入门 五大对象

2010-07-18 12:54  ※森林小居※  阅读(1767)  评论(0编辑  收藏  举报

 1. ADO.NET 3.0 用于访问和操作数据的两个主要组件是: .NET Framework 数据提供程序 (虚线框内) 和 DataSet。

  .NET Framework 数据提供程序是专门为数据操作以及快速、只进、只读访问数据而设计的组件。

  ADO.NET DataSet 是专门为独立于任何数据源的数据访问而设计的。

  对象

  说明

  Connection

  建立与特定数据源的连接。 所有 Connection 对象的基类均为 DbConnection 类。

  Command

  对数据源执行命令。 公开 Parameters,并可在 Transaction 范围内从 Connection 执行。

  所有 Command 对象的基类均为 DbCommand 类。

  DataReader

  从数据源中读取只进且只读的数据流。 所有 DataReader 对象的基类均为 DbDataReader 类。

  DataAdapter

  使用数据源填充 DataSet 并解决更新。 所有 DataAdapter 对象的基类均为 DbDataAdapter 类。

  注意:新手面试经常会遇到考这样的题:ADO.NET 的五大对象,就是 上面四种 + DataSet 要牢牢记住哦。后期开发也经常用到。

  2. Connection 对象(只介绍SqlConnection和JDBC)

  使用connection连接的时候记得打开、关闭(返回连接池),

  建议使用using,这样就不会忘记关了,将自动断开连接,即使发生无法处理的异常。

  string connectionString = "数据库连接字符串";

  using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); .... }

  ODBC 比较麻烦 请参考微软技术文档:http://support.microsoft.com/kb/310988 (我很少用到)

  using (OdbcConnection connection = new OdbcConnection(connectionString)) { connection.Open(); .... }

  3.Command对象

  命令

  返回值

  ExecuteReader

  返回一个 DataReader 对象。

  ExecuteScalar

  返回数据库查询出来的第一行第一列。

  ExecuteNonQuery

  执行增删改命令。

  ExecuteXMLReader

  返回 XmlReader。 只用于 SqlCommand 对象。

  下面用一个实例讲解Connection 和 Command、DataReader以及储存过程和参数的设置:

  (1.)下载安装微软提供的Northwind数据库:

  /Files/Simcoder/微软提供的数据库.rar 含帮助文档 简单容易操作 数据库安装后 文件默认在C盘 然后附加即可

  (2.)找到提供的存储过程:(本实例 使用倒数第二个 SalesByCategory 存储过程做演示)

  (3.)简单查看一下存储过程的代码,其实通过名字都能知道大概做什么用

  

 


---------------------- *创*建*存*储*过*程* -----------------------
  set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go ALTER PROCEDURE [dbo].[SalesByCategory]
  --修改存储过程[SalesByCategory] @CategoryName nvarchar(15), @OrdYear nvarchar(4) = '1998'
  --设置参数 (以下的实现暂不用管) AS IF @OrdYear != '1996' AND @OrdYear != '1997' AND @OrdYear != '1998'
  BEGIN SELECT @OrdYear = '1998' END SELECT ProductName,
  TotalPurchase=ROUND(SUM(CONVERT(decimal(14,2), OD.Quantity * (1-OD.Discount) * OD.UnitPrice)), 0)
  FROM [Order Details] OD, Orders O, Products P, Categories C WHERE OD.OrderID = O.OrderID
  AND OD.ProductID = P.ProductID AND P.CategoryID = C.CategoryID
  AND C.CategoryName = @CategoryName AND SUBSTRING(CONVERT(nvarchar(22), O.OrderDate, 111), 1, 4) = @OrdYear
  GROUP BY ProductName ORDER BY ProductName
  ---------------------- *执*行*存*储*过*程* ----------------------- USE [Northwind] GO DECLARE
  @return_value int EXEC @return_value = [dbo].[SalesByCategory] @CategoryName = N'Produce',
  @OrdYear = N'1998' SELECT 'Return Value' = @return_value
  GO --需要设置@CategoryName,@OrdYear(可以不设置 为空上面有判断)参数值

 

  查询结果是:

  (4.)新建一个控制台的应用程序 代码如下:

 


 using System;
  using System.
  Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Data.SqlClient;
  using System.Data;
  namespace ConsoleApplication1
  { class Program
  { static void Main(string[] args)
  {
  GetSalesByCategory("server=.;uid=sa;pwd=123456;database=Northwind", "Produce");
  //在这里就默认设置了 参数@CategoryName参数的值为 Produce
  }
  static void GetSalesByCategory(string connectionString,string categoryName)
  {
  using (SqlConnection connection = new SqlConnection(connectionString))
  {
  SqlCommand command = new SqlCommand();
  command.Connection = connection;
  command.CommandText = "SalesByCategory";
  //CommandType 属性设置为 StoredProcedure 时,CommandText 属性应设置为存储过程的名称
  command.CommandType = CommandType.StoredProcedure; //设置执行类型为存储过程
  SqlParameter parameter = new SqlParameter();
  parameter.ParameterName = "@CategoryName";
  //指定存储过程中的那个参数
  parameter.SqlDbType = SqlDbType.NVarChar;
  //指定数据类型
  parameter.Direction = ParameterDirection.Input
  ;//指定参数为输入
  parameter.Value = categoryName;
  command.Parameters.Add(parameter);
  connection.Open();
  SqlDataReader reader = command.ExecuteReader();
  if (reader.HasRows)
  //判断是否有数据行
  {
  while (reader.Read())
  {
  Console.WriteLine("{0}: {1:C}", reader[0], reader[1]);
  }
  }
  else
  {
  Console.WriteLine("No rows found.");
  }
  reader.Close();//记得关闭
  Console.ReadLine();
  }
  }
  }
  }

 

  前面简单提到了 Connection 、DataReader、Comand以及参数和存储过程的用法,现在更加深入的学习。

1.DataReader的用法:

  DataReader 从数据库中检索只读、只进的数据流。查询结果在查询执行时返回,在并存储在客户端的网络缓冲区中,

  直到您使用 DataReader 的 Read 方法对它们发出请求。 使用 DataReader 可以提高应用程序的性能,

  原因是它只要数据可用就立即检索数据,并且(默认情况下)一次只在内存中存储一行,减少了系统开销。

  例子见上一篇即可,说说使用DataReader的心得,在做项目中,有时候一个实体类中的字段又是另外一个实体雷,

  存在外键的关系。如下实体类源码 中就有2个这样的关系(高亮代码):

 


 using System;
  using System.Collections.Generic;
  using System.Text;
  namespace BookShop.Model
  {
  [Serializable]
  public class Book
  {
  /// 
  /// 图书编号
  /// 
  private int id;
  public int Id
  {
  get { return id; }
  set { id = value;
  }
  }
  /// 
  /// 图书标题
  /// 
  private string title;
  public string Title
  {
  get { return title; }
  set { title = value;
  }
  }
  /// 
  /// 图书作者
  /// 
  private string author;
  public string Author
  {
  get { return author; }
  set { author = value;
  }
  }
  /// 
  /// 图书出版社
  /// 
  private Publisher publisher;
  public Publisher Publisher
  {
  get { return publisher;
  }
  set { publisher = value;
  }
  }
  /// 
  /// 图书出版日期
  /// 
  private DateTime publishDate;
  public DateTime PublishDate
  { get { return publishDate;
  }
  set { publishDate = value;
  }
  }
  /// 
  /// 图书ISBN编号
  /// 
  private string isbn;
  public string Isbn
  {
  get { return isbn;
  }
  set { isbn = value;
  }
  }
  /// 
  /// 图书总字数
  /// 
  private int wordsCount;
  public int WordsCount
  {
  get
  { return wordsCount; }
  set { wordsCount = value; }
  }
  /// 
  /// 图书价格
  /// 
  private decimal unitPrice;
  public decimal UnitPrice
  {
  get { return unitPrice; }
  set { unitPrice = value; }
  }
  /// 
  /// 图书描述
  /// 
  private string contentDescription;
  public string ContentDescription
  {
  get { return contentDescription; }
  set { contentDescription = value; }
  }
  /// 
  /// 图书作者描述
  /// 
  private string authorDescription;
  public string AuthorDescription
  {
  get { return authorDescription; }
  set { authorDescription = value; }
  }
  /// 
  /// 图书作者评语
  /// 
  private string editorComment;
  public string EditorComment
  {
  get { return editorComment; }
  set { editorComment = value; }
  }
  /// 
  /// 图书目录
  /// 
  private string toc;
  public string Toc
  {
  get { return toc; }
  set { toc = value; }
  }
  /// 
  /// 图书的分类
  /// 
  private Category category;
  public Category Category
  {
  get { return category; }
  set { category = value; }
  }
  /// 
  /// 图书点击
  /// 
  private int clicks;
  public int Clicks
  {
  get { return clicks; }
  set { clicks = value; }
  }
  }
  }

 

  如果是这种关系,使用Datareader 就可能会出现异常,因为当代码读到 外键的时候,外键也要使用connection连接 这时就会抛出异常,所以

  与数据进行动态交互,例如绑定到 Windows 窗体控件或组合并关联来自多个源的数据。

  对数据执行大量的处理,而不需要与数据源保持打开的连接,从而将该连接释放给其他客户端使用。就使用DataSet或DataTable比较合适。