1. ADO.NET 3.0 用于访问和操作数据的两个主要组件是: .NET Framework 数据提供程序 (虚线框内) 和
.NET Framework 数据提供程序是专门为数据操作以及快速、只进、只读访问数据而设计的组件。
ADO.NET DataSet 是专门为独立于任何数据源的数据访问而设计的。
对象 |
说明 |
---|---|
Connection |
建立与特定数据源的连接。 所有 Connection 对象的基类均为 |
Command |
对数据源执行命令。 公开 Parameters,并可在 Transaction 范围内从 Connection 执行。 所有 Command 对象的基类均为 |
DataReader |
从数据源中读取只进且只读的数据流。 所有 DataReader 对象的基类均为 |
DataAdapter |
使用数据源填充 DataSet 并解决更新。 所有 DataAdapter 对象的基类均为 |
注意:新手面试经常会遇到考这样的题:ADO.NET 的五大对象,就是 上面四种 + DataSet 要牢牢记住哦。后期开发也经常用到。
2. Connection 对象(只介绍SqlConnection和JDBC)
使用connection连接的时候记得打开、关闭(返回连接池),建议使用using,这样就不会忘记关了,将自动断开连接,即使发生无法处理的异常。
- 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 |
返回 |
下面用一个实例讲解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
- {
- /// <summary>
- /// 图书编号
- /// </summary>
- private int id;
- public int Id
- {
- get { return id; }
- set { id = value; }
- }
- /// <summary>
- /// 图书标题
- /// </summary>
- private string title;
- public string Title
- {
- get { return title; }
- set { title = value; }
- }
- /// <summary>
- /// 图书作者
- /// </summary>
- private string author;
- public string Author
- {
- get { return author; }
- set { author = value; }
- }
- /// <summary>
- /// 图书出版社
- /// </summary>
- private Publisher publisher;
- public Publisher Publisher
- {
- get { return publisher; }
- set { publisher = value; }
- }
- /// <summary>
- /// 图书出版日期
- /// </summary>
- private DateTime publishDate;
- public DateTime PublishDate
- {
- get { return publishDate; }
- set { publishDate = value; }
- }
- /// <summary>
- /// 图书ISBN编号
- /// </summary>
- private string isbn;
- public string Isbn
- {
- get { return isbn; }
- set { isbn = value; }
- }
- /// <summary>
- /// 图书总字数
- /// </summary>
- private int wordsCount;
- public int WordsCount
- {
- get { return wordsCount; }
- set { wordsCount = value; }
- }
- /// <summary>
- /// 图书价格
- /// </summary>
- private decimal unitPrice;
- public decimal UnitPrice
- {
- get { return unitPrice; }
- set { unitPrice = value; }
- }
- /// <summary>
- /// 图书描述
- /// </summary>
- private string contentDescription;
- public string ContentDescription
- {
- get { return contentDescription; }
- set { contentDescription = value; }
- }
- /// <summary>
- /// 图书作者描述
- /// </summary>
- private string authorDescription;
- public string AuthorDescription
- {
- get { return authorDescription; }
- set { authorDescription = value; }
- }
- /// <summary>
- /// 图书作者评语
- /// </summary>
- private string editorComment;
- public string EditorComment
- {
- get { return editorComment; }
- set { editorComment = value; }
- }
- /// <summary>
- /// 图书目录
- /// </summary>
- private string toc;
- public string Toc
- {
- get { return toc; }
- set { toc = value; }
- }
- /// <summary>
- /// 图书的分类
- /// </summary>
- private Category category;
- public Category Category
- {
- get { return category; }
- set { category = value; }
- }
- /// <summary>
- /// 图书点击
- /// </summary>
- private int clicks;
- public int Clicks
- {
- get { return clicks; }
- set { clicks = value; }
- }
- }
- }
如果是这种关系,使用Datareader 就可能会出现异常,因为当代码读到 外键的时候,外键也要使用connection连接 这时就会抛出异常,所以
与数据进行动态交互,例如绑定到 Windows 窗体控件或组合并关联来自多个源的数据。
对数据执行大量的处理,而不需要与数据源保持打开的连接,从而将该连接释放给其他客户端使用。就使用DataSet或DataTable比较合适。
也许你不太明白,但是你可以这样简单的记住,当实体类或数据库设计存在主外键关系的时候,使用Datareader就要谨慎了! 不过也没关系,很多经验都是从Debug学到的。
就好像微软的视频一样,为爱Debug。
原文标题:ADO.NET快速上手(一)
链接:http://www.cnblogs.com/Simcoder/archive/2010/05/03/1726295.html