480 likes | 719 Views
5 .NET 数据库开发. 主要内容. 5.1 ADO.NET 基础 5.2 使用 ADO.NET 进行数据库开发 5.3 一个示例. 5.1.1 数据访问发展简述. 1 . ODBC 在 20 世纪 90 年代初, Microsoft 和其他几家公司都开发了 ODBC ( Open Database Connectivity ,开放数据库连接)。它提供了一个公共数据访问层,可用来访问几乎所有的 RDBMS ( Relational Database Management System ,关系型数据管理系统 ) ,
E N D
主要内容 • 5.1 ADO.NET基础 • 5.2 使用ADO.NET进行数据库开发 • 5.3 一个示例
5.1.1数据访问发展简述 1.ODBC • 在20世纪90年代初,Microsoft和其他几家公司都开发了ODBC(Open Database Connectivity,开放数据库连接)。它提供了一个公共数据访问层,可用来访问几乎所有的RDBMS(Relational Database Management System,关系型数据管理系统), • ODBC最重要的特性是,它是一个开放标准,甚至己被开放源代码团体广泛采用。
5.1.1数据访问发展简述(2) 2.DAO(Data Access Objects) • DAO提供了一个可与Jet交互的简单对象模型,Jet是Microsoft Access桌面数据库的数据库引擎。 3.RDO(Remote Data Object) • RDO提供了一个与DAO相似的简单对象模型,该模型专门用于访问ODBC数据源,RDO实质上是ODBC API上的一个薄层。
5.1.1数据访问发展简述(3) 4.OLE DB (Object Linking and Embedding, Database) • OLE DB提供者实现了一组COM接口,它可访问标准行/列格式的数据。 5.ADO • ADO(ActiveX Data Objects,ActiveX数据对象)ADO只是一个OLE DB客户──它是一个薄层,允许用户使用诸如VB和脚本语言等高级语言通过简单对象模型来访问OLE DB数据源。
5.1.2 ADO.NET简介 • ADO.NET优于从.NET中调用ADO的特点: 1.使用管理类的优点 2.跨语言支持 3.更清晰的结构 4.XML支持 5.优化的对象模型
5.1.3 ADO.NET体系结构 • ADO.NET对象模型由两个基本组件组成: • 一个是数据集(DataSet) • 另一个是.NET Framework数据提供者(.NET Framework data provider)
.NET Framework数据提供者 • 每个提供者都位于System.Data命名空间内的一个命名空间中,并且由许多类构成。提供者可以为任何数据源编写.NET Framework数据提供程序。 • .NET Framework提供了四个.NET Framework数据提供者: • SQL Server (System.Data.SqlClient) • OLE DB (System.Data.OleDb) • ODBC (System.Data.Odbc) • Oracle (System.Data.OracleClient)
数据提供者对象 • Connection对象──提供与数据源的连接。 • Command对象──能够访问用于返回数据、修改数据、运行存储过程以及发送或检索参数信息的数据库命令。 • DataReader对象──从数据源中提供高性能的数据流,是一个已连接的、前向只读结果集。 • DataAdapter对象──提供连接DataSet对象和数据源的桥梁。DataAdapter使用Command对象在数据源中执行SQL命令,以便将数据加载到DataSet中,并使对DataSet中数据的更改与数据源保持一致。
5.1.4 建立与数据库的连接 操作一个Access数据库: string myConnString = "server=localhost;database=Northwind;uid=sa;pwd=;"; SqlConnection myConn = new SqlConnection(myConnString); myConn.Open(); //Do something useful myConn.Close();
ODBC方式 • 配置ODBC数据源 • 控制面板->管理工具->数据源 (ODBC)->系统DSN
ODBC方式 连接字符串 string connectString = @"Provider=System.Data.Odbc;"; connectString += "Dsn=PostgreSQL35W;database=postgres;"; connectString += "server=localhost;port=5432;"; connectString += "uid=test;pwd=123456";
主要内容 • 5.1 ADO.NET基础 • 5.2 使用ADO.NET进行数据库开发 • 5.3 一个示例
5.2.1 数据库查询 1.创建Command对象 string strConn,strSQL; strConn = "server=localhost;database=Northwind;uid=sa;pwd=;"; strSQL = "select CustomerID,CompanyName from Customers"; SqlConnection myConn = new SqlConnection(strConn); myConn.Open(); SqlCommand cmd;
5.2.1 数据库查询 1.创建Command对象 //第一种方式 cmd = myConn.CreateCommand(); cmd.CommandText = strSQL; //第二种方式 cmd = new SqlCommand(); cmd.CommandText = strSQL; cmd.Connection = myConn; //第三种方式 Cmd = new SqlCommand(strSQL,myConn);
5.2.1 数据库查询 2.执行无返回行的查询 • 不返回结果集的查询通常称为操作查询(action query),操作查询有两种主要类型: • 数据操纵语言(DML,Data manipulation language)查询。如update、insert或delete语句。 • 数据定义语言(DDL,Data definition language)查询,会更改数据库的结构,如create table、alert view或drop procedure等语句。
5.2.1 数据库查询 • 例如: SqlConnection myConn = new SqlConnection(); myConn.ConnectionString = "server=localhost;database=Northwind;uid=sa;pwd=;"; myConn.Open(); SqlCommand cmd = myConn.CreateCommand(); cmd.CommandText = "update Customers set CompanyName='NewCompanyName'" + "where CustomerID ='ALFKI'"; cmd.ExecuteNonQuery();
5.2.1 数据库查询 3.用DataReader对象检查查询结果 • Command对象提供了一个ExecuteReader方法,该方法能够返回DataReader对象,可通过此对象检查查询结果。 连接模型
5.2.1 数据库查询 • 例如: string strConn,strSQL; strConn = "server=localhost;database=Northwind;uid=sa;pwd=;"; SqlConnection myConn = new SqlConnection(strConn); myConn.Open(); strSQL = "select CustomerID,CompanyName from Customers"; SqlCommand cmd = new SqlCommand(strSQL,myConn); SqlDataReader dr = cmd.ExecuteReader(); while(dr.Read()) Console.WriteLine(dr["CustomerID"] + "-" + dr["CompanyName"]); dr.Close();
5.2.1 数据库查询 获取多个结果 SqlCommand cmd = new SqlCommand(strSQL,myConn); SqlDataReader dr = cmd.ExecuteReader(); do { while(dr.Read()) Console.WriteLine(dr[0] + "-" + dr[1]); Console.WriteLine(); }while(dr.NextResult());
5.2.1 数据库查询 4.执行返回单值的查询 假设想执行一个查询,并获取单个数据元素(如一行,一列),用DataReader或DataSet来获取单值可能有些大材小用。Command对象有一种专为该类查询设计的方法:ExecuteScalar。
5.2.1 数据库查询 5.执行参数化查询 …… strSQL = "select OrderID,CustomerID,EmployeeID,OrderDate from" + " Orders where CustomerID=@CustomerID"; SqlCommand cmd = new SqlCommand(strSQL,myConn); cmd.Parameters.Add("@CustomerID",SqlDbType.Char,8); cmd.Parameters[0].Value = "ALFKI"; SqlDataReader dr = cmd.ExecuteReader();
5.2.2 DataAdapter对象 • DataAdapter类可以看作是ADO.NET结构的电子“插头”。 • 该适配器在生命周期内的惟一目的就是填充DataSet,以及向数据源传送DataSet的改变。 无连接模型
5.2.2 DataAdapter对象 • 适配器实际上是4个独立的Command对象的容器,即SelectCommand、InsertCommand、UpdateCommand和DeleteCommand。
5.2.3 DataSet类 • DataSet是提供内存数据存储的所有功能的类。它维护完全非连接的数据缓存。
DataTable 该表是一个列的有条理的集合,并拥有许多的关联行。 ⑴ Columns Columns集包含了表内所有列的列表。 ⑵ Constraints 约束是应用于表的数据规则。它为一集合对象。 ⑶ ChildRelations 关系集,用来定义建立该DataTable子表的关系。
⑷ ParentRelations 该集合包含了用于建立该DataTable的父表的所有关系的列表。 ⑸ PrimaryKey PrimaryKey属性是用于描述包含一个特定的DataTable的主键的所有列的DataColumn对象的数组,它允许相当健壮和复杂的数据存储于DataSet中。 ⑹ Rows 而Rows集合提供了包含在该表中的实际数据。它包含DataRow对象集。
DataColumn DataColumn是构建DataTable模式的核心,定义DataColumn时,要提供数据类型、尺寸,以及用于控制表内数据如何访问的名称信息。 常用的属性: ⑴ AllowDBNull 为Boolean标志,指示在父级表列中每行的列是否允许为null。 ⑵ AutoIncrement 另一Boolean标志,指示对于新插入到父级表列中的新行,列是否会自动增加列值。
⑶ DataType DataType属性并不使用枚举或一些易错的数据类型编码系统,实际上它能存储实际的.NET Framework数据类型。 ⑷ ReadOnly 为一Boolean标志,指示表中的列值是否可以修改。 ⑸ Unique 为一Boolean标志,指示表中所有行的列的所有值必须保证是惟一的。
DataRow • DataRow是表内数据行的格式化的、结构化的数据容器。DataRow对象为表内的数据行容纳了Create、Retrieve、Update和Delete功能。
⑴ RowState • RowState属性属于枚举类型DataRowState。它告诉程序员(以及GetChanges()和HasChanges()方法)DataRow的当前状态。该状态可由下列枚举值的之一来表示。 • Added:行已加入表中,然而AcceptChanges()方法还未调用。 • Deleted:行已使用DataRow的Delete()方法删除。 • Detached:行实际上不是表的一部分;或者刚创建,还没有成为集合的一部分;或者刚刚从集合中删除。 • Modified:行内的数据已修改,然而AcceptChanges()还未调用。 • Unchanged:自从上次AcceptChanges()调用后,行内数据没有改变。
⑵ Item • Item属性经常被重载,以允许使用多种不同的方法得到存储在行中的指定列的数据。可以提供列名,来设置和读取值。可以提供DataColumn对象,同样来设置和渎取该值。另外,可以提供列的顺序位置来设置和读取值。 ⑶ BeginEdit() • 该函数使DataRow处于编辑模式,来暂时延缓事件触发,以允许同时修改不只一行数据。程序员可通过使几行处于编辑模式来延缓有效验证,装载数据,然后进行修改。
⑷ CancelEdit() • 该函数使DataRow脱离编辑模式,并放弃自从调用BeginEdit()方法后对行所做的改变。 ⑸ Delete() • 该函数删除当前行。
⑹ EndEdit() • 该函数使当前行完成编辑模式,存储自调用BeginEdit()方法后对DataSet所做的改变。 ⑺ AcceptChanges() • 该函数隐式调用EndEdit ()方法。若在该函数调用前行的RowState是Added或Modified,RowState就成为Unchanged。如果在函数调用前RowState是Deleted,则RowState被物理上删除。
5.2.5 XML与ADO.NET ① DataSet的结构(表、列、关系和约束)可在XML架构中定义。 ② 可以使用DataSet的ReadXML方法将XML文档或流读入DataSet,使用DataSet的WriteXML方法将DataSet以XML格式写出。 ③ 可以创建DataSet内容的XML视图(XMLDataDocument对象),然后用关系方法(通过DataSet)或XML方法查看和操作数据。这两种视图在更改时自动同步。
5.2.5 XML与ADO.NET 1.GetXml方法 • GetXml方法,可以用它将DataSet的内容提取为字符串。 2.WriteXml和ReadXml方法 • 将DataSet的内容写入一个文件或者一个实现了Stream、TextWriter或者XMLWriter界面的对象。
小结 2-1 • DataAdapter类在生命周期内的惟一目的就是填充DataSet,以及向数据源传送DataSet的改变。 • DataAdapter适配器实际上是4个独立的Command对象的容器,即SelectCommand、InsertCommand、UpdateCommand和DeleteCommand。 • DataSet是提供内存数据存储的所有功能的类。它维护完全非连接的数据缓存。包含表集、表间的关系、表的限制和键值,以及每个表包含行和列的集合。
小结 2-2 • DataAdapter的Fill方法用于使用SelectCommand的结果来填充DataSet。Fill将要填充的DataSet和DataTable对象用作它的参数。 • DataAdapter的Update方法可用来将DataSet中的更改解析回数据源。 • 用DataSet对象读写XML数据的方法有:GetXml、WriteXml、ReadXml方法等。
主要内容 • 5.1 ADO.NET基础 • 5.2 使用ADO.NET进行数据库开发 • 5.3 一个示例
数据库 • PlayList.mdb
获取和显示PlayList string connectString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\DotNetExample\DB\PlayList.mdb"; OleDbConnection aConnection = new OleDbConnection(connectString); string commandStr; OleDbCommand aCommand; commandStr = "Select distinct ListName from PlayList"; aConnection.Open(); OleDbDataReader rd; aCommand = newOleDbCommand(commandStr, aConnection); rd = aCommand.ExecuteReader(); this.playList.Items.Clear(); while (rd.Read()) { string file = rd.GetString(0); this.playList.Items.Add(file); } rd.Close(); aConnection.Close(); this.playList.Refresh();
打开一个PlayList string listname; int idx1 = playList.SelectedIndex; listname = playList.Items[idx1].ToString(); OleDbConnection aConnection = new OleDbConnection(connectString); string commandStr; OleDbCommand aCommand; commandStr = "Select distinct FileName from PlayList where ListName='" + listname + "'"; aConnection.Open(); OleDbDataReader rd ; aCommand = newOleDbCommand(commandStr, aConnection); rd = aCommand.ExecuteReader(); this.imageList.Items.Clear(); while (rd.Read()) { string file; file = rd.GetString(0); this.imageList.Items.Add(file); } rd.Close(); aConnection.Close(); this.imageList.Refresh();
保存一个PlayList string listname = listName.Text; OleDbConnection aConnection = new OleDbConnection(connectString); aConnection.Open(); string commandStr; OleDbCommand aCommand; int index; int listNumber = this.imageList.Items.Count; for(index = 0; index < listNumber; index++) { string file = imageList.Items[index].ToString(); commandStr = "insert into PlayList values('" + listname + "','" + file + "')"; aCommand = newOleDbCommand(commandStr, aConnection); aCommand.ExecuteNonQuery(); } aConnection.Close();