C# 数据库操作

1,ADO.NET 类和对象概述

类分为.NET 数据提供者对象和用户对象

提供者对象专用于每种类型数据源,专用于提供者的对象完成数据源中实际的读取和写入工作。

用户对象是将数据读入内存中后来访问和操纵数据的对戏那个。

提供者需要一个活动的连接,可以读取,写入,更新数据源中的数据。用户对象以非连接的方式使用,甚至在数据库关闭之后,也可以使用内存中的数据。

2,提供者对象

【1】连接对象:提供了数据源的基本连接,类似于ADO中的Connection字串的连接。

【2】命令对象:可以使用此对象给数据源发出命令,比如:“select * from customers”查询等,对于不同的提供者,该对象的名称而不同,SQL Server 的SqlCommand,用于ODBC的OdbcCommand,用于OLE DB 的OleDbCommand

【3】CommandBuilder对象

用于构建SQL命令,在基于单一表查询的对象中进行数据修改。对于不用的提供者名称有所不同,SqlCommandBuilder,OdbcCommandBuilder,OleDbCommandBuilder.

【4】DataReader 对象

这是一个快速和易用的对象,可以从数据源中读取仅能前向和只读的数据流,对于简单的读取数据来说,此对象的性能最好。对于不同的提供者,名称有所不同。分别:SqlDataReader,OdbcDataReader,OleDbDataReader

【5】DataAdapter对象

这是一个通用的类,可以执行针对数据源的各种操作,包括更新变动的数据,填充DataSet对象以及其他操作。对于不同的提供者名称有所不同。分别:SqlDataAdapter,OdbcDataAdapter,OleDbDataAdapter

3,用户对象

【1】DataSet对象

DataSet对象是用户对象中的首要对象,此时对象表示一组相关表,在应用程序中这些表作为一个单元来引用。例如:Customer,Orders和Products是一个DataSet中的表,他们表示每一位顾客和他们从公司中订购的产品,有了此对象,可以快捷的从每一个表中获取需要的数据,当与服务区断开时检查并修改数据,然后在另一个操作中使用这些修改的数据更新服务器。DataSet允许访问低级对象,这些对象代表单独的表和关系。这些对象是DataTable对象和DataRelation对象。

【2】DataTable对象

此对象代表DataSet中的一个表。例如:Customer,Orders或Products

DataTable对象允许访问其中的行和列:

DataColumn对象:代表表中的一列

DataRow对象:代表表中的一行

【3】DataRelation对象

此对象代表通过共享列而发生关系的两个表之间的关系,例如Order表中的CustomerID列标示发出订单的客户。于是,可以创建DataRelation对象,通过共享列CustomerID建立Customer和Order表之间的联系。

4,使用System.Data命名空间

在C#代码中使用ADO.NET的第一步是引用System.Data命名空间,其中包含所有的Ado.Net类,将下面using指令放在使用Ado.net程序的开端:

using System.Data;

接着需要为使用的特定数据源引用.NET数据提供者。

【1】SQL Server .NET 数据提供者

使用专用的内置.NET 数据提供者就可以获得最好的性能和对基础功能的最直接访问。

using System.Data.SqlClient;

【2】Oracle .NET 数据提供者

使用Oracle数据库,内置Oracle .NET驱动程序是最佳选择。项目文件上点击右键,选择添加引用,然后找到.net选项卡的System.Data.OracleClient,点击确认即可。(比上面麻烦一些)然后就可以用下面的语句。

using System.Data.OracleClient;

Oracle本身也提供了一个.NET数据提供者,引用为Oracle.DataAccess.Client,它必须从Oracle中单独下载。这个驱动可以更多的利用数据库产品的特定功能,但对于基本的使用来说,都可以。

【3】OLE DB.NET数据提供者

对于不是SQLServer或Oracle的数据源(例如Access),可以使用OLE DB.NET 数据提供者。

using System.Data.OleDb;

【4】ODBC.NET数据提供者

using System.Data.Odbc;

5,用DataReader读取数据

程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;              //注意
using System.Data.OracleClient; //Oracle数据库

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            //Data Source=orcl;User ID=shibei;Password=nsic;Unicode=True

            OracleConnection myConnection = new OracleConnection(@"Data Source=orcl;User ID=shibei;Password=nsic;Unicode=True");//创建连接对象
            myConnection.Open();      //建立连接

            OracleCommand myCommand = myConnection.CreateCommand(); //创建命令对象
            myCommand.CommandText = "select * from N_AIT";          //提供SQL命令
            OracleDataReader myReader = myCommand.ExecuteReader();  //执行命令返回结果指派给DataReader对象

            while (myReader.Read())                                 //从读取器中获取结果
            {
                Console.WriteLine("{0}\t{1}", myReader["ID"], myReader["NAME"]);
            }
            myReader.Close();//关闭DataReader
            myConnection.Close();//关闭数据库连接
        }
    }
}

运行结果:

tmp7B

注意:如果本例要使用OleDb进行连接的话,除了把using System.Data.OracleClient; 改成using System.Data.OleDb;把OracleConnection等改成OleDbConnection等。唯一的区别就是连接字符串,生成连接字符串的方法可以在。数据-显示数据源-添加新数据源。配置好之后就可以看到连接字符串了,一定要包含敏感字符啊,不然密码就没了,呵呵。

6,用DataSet读取数据

DataSet是Ado.Net中的核心对象,所有复杂级别的操作都使用它。DataSet包含一组DataTable对象,他们表示操作的数据库表。DataSet的常见操作使用DataAdapter对象Fill方法给他填充数据为什么Fill方法是DataAdapter对象的方法,而不是DataSet的方法呢,因为DataSet是内存中数据的一个抽象表示,而DataAdapter对象是把DataSet和具体的数据库联系起来的对象,Fill方法有很多重载版本,本例中使用两个参数的,第一个指定要填充的DataSet,第二个参数是DataSet中要包含所加载数据的DataTable名称。DataSet对象有一个Tables属性,他是DataSet中所有DataTable对象的集合。Tabels的类型是DataTableCollection,他有一个重载的索引符,于是可以用两种方式访问每个DataTable

【1】按表名访问:thisDataSet.Tables[“Customers”]

【2】按索引访问:thisDataSet.Tables[0]

每一个DataTable都有一个Rows属性,他是DataRow对象的集合。Rows的类型是DataRowCollection,是一个有序列表,按行号排序。例:myDataSet.Tables[“Customers”].Rows[n]表示在thisDataSet的DataTable对象Customers中指定行号n-1(索引是基于0的)。当然也可以使用其他索引语法来制定DataTable。我们希望DataRow也有一个DataColumnCollection类型的属性,但是事实并不是那么简单,因为要利用那个每一行各个列中的数据类型,是包含字符数据的列是一个字符串,包含整数的列是一个整数对象等等。DataRow有一个重载的索引,允许按列名和列号访问各个列。

thisDataSet.Table[“Customers”].Rows[n][“CompanyName”]

在thisDataSet的DataTable对象Customers中指定行号为n-1的CompanyName列,这里DataRow对象是thisDataSet.Tables[“Customers”].Rows[n],上述结构有点混乱,给出了其图形显示。

tmp7C

程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;              //注意
using System.Data.OracleClient; //Oracle数据库

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {
            //Data Source=orcl;User ID=shibei;Password=nsic;Unicode=True

            OracleConnection thisConnection = new OracleConnection(@"Data Source=orcl;User ID=shibei;Password=nsic;Unicode=True");
          
            //  thisConnection.Open();//此处可以不用打开     

            OracleDataAdapter thisAdapter = new OracleDataAdapter("select * from N_AIT", thisConnection);

            DataSet thisDataSet = new DataSet();

            thisAdapter.Fill(thisDataSet, "MY_N_AIT");//MY_N_AIT不是表名而是DataTable对象的名称

            foreach (DataRow theRow in thisDataSet.Tables["MY_N_AIT"].Rows)//注意与上面的MY_N_AIT要对上哦
            {
                Console.WriteLine(theRow["ID"] + "\t" + theRow["NAME"]);//除了用名字也可以用索引号
            }

            thisConnection.Close();//这个例子中没有明确打开连接,因为DataAdapter对象完成了这个工作,
                                   //数据授权对象会根据需要打开连接,在完成工作后关闭它。
                                   //DataAdapter对象不改变连接的状态,如果DataAdapter对象开始其工作前连接时打开的,
                                   //在DataAdapter对象完成其工作后,连接仍是打开的。( 不懂既然DataAdapter来处理为什么不改变连接的状态)
            
        }
    }
}

运行结果同上。

注意:DataReader工作时必须要维护数据库的连接,而且只能向前的方式读取数据,可以浏览记录或跳到某一记录上。而且只能读取记录。而用DataAdapter对象填充了DataSet,DataAdapter对象需要处理连接的打开和关闭。DataSet为数据的读写以及操作不同数据源中的数据提供了极大的灵活性。下面相继介绍。

7,更新数据库

本例中给出一个非常简单的示例,此示例仅使用了一个表,同时引入后面才会介绍的几个新对象。

在数据库上进行的操作(更新,插入,删除)可以用相同的模式完成。

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;              //注意
using System.Data.OracleClient; //Oracle数据库

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {

            OracleConnection thisConnection = new OracleConnection(@"Data Source=orcl;User ID=shibei;Password=nsic;Unicode=True");

            OracleDataAdapter thisAdapter = new OracleDataAdapter("select * from N_AIT", thisConnection);

            OracleCommandBuilder thisBuilder = new OracleCommandBuilder(thisAdapter);//CommandBuilder用来创建SQL指令,与Adapter相关联

            DataSet thisDataSet = new DataSet();

            thisAdapter.Fill(thisDataSet, "MY_N_AIT");//MY_N_AIT不是表名而是DataTable对象的名称

            Console.WriteLine("Name before change:{0}", thisDataSet.Tables["MY_N_AIT"].Rows[4]["NAME"]);

            thisDataSet.Tables["MY_N_AIT"].Rows[4]["NAME"] = "被我改了";//数据被修改

            thisAdapter.Update(thisDataSet, "MY_N_AIT");//SQL的指令时靠CommandBuilder来完成的,这要求建立Adapter的查询语句中的字段
                                                        //必须有主键,如果没有的话这样执行就抛出异常了。
            

            thisConnection.Close();//这个例子中没有明确打开连接,因为DataAdapter对象完成了这个工作,
                                   //数据授权对象会根据需要打开连接,在完成工作后关闭它。
                                   //DataAdapter对象不改变连接的状态,如果DataAdapter对象开始其工作前连接时打开的,
                                   //在DataAdapter对象完成其工作后,连接仍是打开的。( 不懂既然DataAdapter来处理为什么不改变连接的状态)
            
        }
    }
}

运行结果:

tmp41

实际数据库中数据将被改写:

tmp42

注意:利用OracleCommandBuilder产生SQL语句,但是表中必须要有主键,否则会抛出异常。采用直接执行SQL命令可以解决。

8,直接执行SQL命令

程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;              //注意
using System.Data.OracleClient; //Oracle数据库

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {

            OracleConnection thisConnection = new OracleConnection(@"Data Source=orcl;User ID=system;Password=myoracle;Unicode=True");

            thisConnection.Open();//此处可以不用打开     

            OracleCommand thisCommand = thisConnection.CreateCommand();

            thisCommand.CommandText = "select count(*) from Histalamt";

            Object countResult = thisCommand.ExecuteOracleScalar();

            Console.WriteLine("Count = {0}", countResult);

            thisConnection.Close();

            Console.ReadKey();

        }
    }
}

运行结果:

tmp3A

9,不检索数据

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;              //注意
using System.Data.OracleClient; //Oracle数据库

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {

            OracleConnection thisConnection = new OracleConnection(@"Data Source=orcl;User ID=shibei;Password=nsic;Unicode=True");

            thisConnection.Open();//此处可以不用打开     

            OracleCommand thisCommand = thisConnection.CreateCommand();

            thisCommand.CommandText = "update N_AIT set NAME = '改你了,怎么地' where ID = 34251";

            int rows = 0;
            try
            {

                rows = thisCommand.ExecuteNonQuery();//返回行数

                //取出返回值
                Console.WriteLine(Convert.ToString(rows));
            }
            catch (Exception er)
            {
                string merr = "err:" + er.ToString();
                Console.WriteLine(merr);
            }
            finally
            {
                thisConnection.Close();
                thisConnection.Dispose();//释放所有资源
                thisCommand.Parameters.Clear();
                thisCommand.Dispose();//释放所有资源
            }
        }
    }
}

运行结果:

tmp7D

更改后的表:

tmp7E

注意:此方法对删除和插入同样有效哦

10,调用SQL存储过程

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;              //注意
using System.Data.OracleClient; //Oracle数据库

namespace ConsoleApplication4
{
    class Program
    {
        static void Main(string[] args)
        {

            OracleConnection thisConnection = new OracleConnection(@"Data Source=orcl;User ID=system;Password=myoracle;Unicode=True");

            thisConnection.Open();//此处可以不用打开     

            OracleCommand thisCommand = thisConnection.CreateCommand();

            thisCommand.CommandType = CommandType.StoredProcedure;
            thisCommand.CommandText = "or_test";

            int rows = 0;
            string rtnStr;
            try
            {
                OracleParameter[] parm = new OracleParameter[2];
                //in
                parm[0] = new OracleParameter("myid", OracleType.Number, 3);
                parm[1] = new OracleParameter("myname", OracleType.VarChar, 50);

                //指明参数是输入还是输出型
                parm[0].Direction = ParameterDirection.Input;
                parm[1].Direction = ParameterDirection.Output;


                //给参数赋值
                parm[0].Value = 350;


                //传递参数给Oracle命令

                thisCommand.Parameters.Add(parm[0]);
                thisCommand.Parameters.Add(parm[1]);

                rows = thisCommand.ExecuteNonQuery();//返回行数

                //取出返回值
                rtnStr = Convert.ToString(parm[1].Value);//res
                Console.WriteLine(rtnStr);
                Console.WriteLine(Convert.ToString(rows));
            }
            catch (Exception er)
            {
                string merr = "err:" + er.ToString();
                Console.WriteLine(merr);
            }
            finally
            {
                thisConnection.Close();
                thisConnection.Dispose();//释放所有资源
                thisCommand.Parameters.Clear();
                thisCommand.Dispose();//释放所有资源
            }
        }
    }
}

存储过程:

tmp6C

运行结果:

tmp68

posted @ 2013-11-06 15:36  Alex.Net  阅读(230)  评论(0编辑  收藏  举报