C#(一)
因为文章太长了,所以只能打包上传了。
最近在学习C#数据库编程,感觉书上学到的和网上查的资料都比较凌乱,于是就想把这些知识整理一下。也希望能给像我一样正处于入门阶段的朋友有所帮助。
用.Net框架编写的应用程序需要访问数据库时,将使用ADO.NET来实现数据库访问。ADO.NET类型在System.Data命名空间下及其子空间下,它包括为访问SQL Server, OLE DB, ODBC和数据库而优化的类型,而且这些都是基于通用类的。因此,使用ADO.NET访问不同的DBMS是相似的。
ADO.NET主要用来实现两个功能:数据访问和数据表示。
ADO.NET包含7个重要的基类,其中4个是数据访问类,3个是数据表示类。
数据访问类:
1.DbConnection
它主要用来提供与数据库的连接。
2.DbCommand
DbCommand对象可以用来执行SQL语句、运行存储过程等。
3.DbDataReader
此类用来读取执行命令所获得的数据。
4.DbDataAdapter
DbDataAdapter叫数据适配器,它既可以将数据库中的数据传输给包含在DataSet中的表,也可以将DataSet对象中的数据传输给数据库以更新数据源。它相当于是DataSet和数据库的中介。
数据表示类(数据表示类于上面的数据访问类有点不同,数据表示类是独立于各数据库平台的,它们没有专门用于特定数据库管理系统的子类):
1.DataTable
此类用于存储数据表。但它存储的表不一定对映数据库中的表,它是一个临时保存数据的虚拟表。
2.DataRelation
它用来处理多个DataTable对象之间的数据关系。
3.DataSet
它是DataTable和DataRelation对象的集合。我们可以把它当作内存中的数据库,它是从数据源检索到的数据在内存中的缓存。它是一个功能强大的类,这一方面体现在它有很多属性和方法,另一方面体现在与其他对象如:Web应用程度、应用程序、Web服务和XML文档的结合使用上。
当然访问数据和数据绑定也可通过控件和向导来完成,但这往往达不到我们所需要实现的控制程度或不能像我们希望的那样有效。在这种情况下,我们一般会选择以编程的方式访问数据库。
1.数据库连接
第一步是配置连接对象,然后才可以对连接对象执行命令,获得数据。
SqlConnection conn = new SqlConnection();
创建实例后,可用SqlConnection.ConnectionString属性给连接对象配置连接字符串。
conn. ConnectionString= “ConnectionString”;
当然,我们也可以使用构造函数将以上两个步骤合二为一:
SqlConnection conn= new SqlConnection(“ConnectionString”);
在创建SqlConnection对象时,应提供与所使用数据库通信所需的信息,如数据源的位置、用于登录的用户名和密码以及要访问的数据库系统中的某个具体的数据库名。(e.g:Data Source=CHINA-C17C0CDAC\\SQLEXPRESS;User id=sa;PWD=test;Database=FolktaleDB这是一个连接数据库的字符串)其他ADO.NET的数据访问及表示类都依靠它与数据库进行通信,没有它后面的一切皆是浮云。
SqlConnection类有提供属性,便于我们判断当前的连接状态。因为在任何特定时刻,连接可以是打开也可是关闭的。只有在连接打开时才能访问数据库,但数据库连接消耗资源,因此只有代码使用时才打开连接,在其他时候应该关闭,否则可能引起内存泄露或也可能阻止其它程序访问数据库。
连接状态可以通过SqlConnection.State来判断,此属性会返回一个枚举值(Open/Closed)。
if(conn.State ==ConnectionState.Open)
{
//Do things
}
如果使用SqlConnection.Open()打开了连接,则一定要用SqlConnection.Close()方法来关闭它,否则它不会自动关闭的。当然后面会讲到通过数据阅读器关闭连接。
或者我们也可以使用Using块,享受自动关闭。在Using块中,最后一行代码执行完后,将自动关闭连接。
Using(SqlConnection conn=new SqlConnection(“ConnectionString”))
{
conn.Open();
. . .
}
这个Using是怎么做到不需要我们手工关闭的呢?因为它能导致SqlConnection对象的Dispose()方法被调用,这样该方法就把连接给关闭了。
通常我们的代码中一般会这样写:
SqlConnection conn=new SqlConnection(“ConnectionString”)
try
{
conn.Open();
}
catch
{
//Handle exception
}
finally
{
conn.Close();
}
2.数据库命令
SqlCommand对象通过SqlConnection对象对数据库执行命令。SqlCommand类有4个构造函数。其中最简单的是无参构造函数。然后是带一个查询语句的参数。但一般常用的是第三种,它带查询语句和SqlConnection对象。
SqlConnection connection = new SqlConnection (connectionString)
SqlCommand command = new SqlCommand(queryString, connection);
如果构造函数没有参数,则可以通过SqlCommand.CommandText属性来设置。
3.数据阅读器
SqlDataReader类,它提供的数据游标是只向前的,所以它只能以串行的方式一次读取一行数据,而且不能读完几行后再返回去读取,它只能一行一行的往下读。
SqlDataReader类与一般的类有一点不同,它没有可用来创建实例的公有构造函数,所以只能使用SqlCommand.ExecuteReader()来创建SqlDataReader实例。
e.g
SqlCommandcmd =newSqlCommand("Select * from Ending",conn);
SqlDataReaderreader = cmd.ExecuteReader();
通常也可在创建SqlDataReader类实例,设定在关闭数据阅读器的同时关闭连接。
SqlDataReaderreader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
创建SqlDataReader实例后,既可用来读取数据,又可用来获取架构数据。要获取架构数据,可使用SqlDataReader.GetSchemaTable()方法。当然,还有实用的方法:
SqlDataReader.FieldCount()返回一个int值,获取行中的列数
SqlDataReader.GetName()获取指定列的名称
SqlDataReader.GetDataTypeName()获取指定列的数据类型名
下面,就结合一个实例来体会下,上述方法的使用和SqlDataReader是如何来读取数据的。
classProgram
{
staticvoidMain(string[] args)
{
stringstrString ="Data Source= CHINA-C17C0CDAC\\SQLEXPRESS;User id=sa;PWD=test;Database=FolktaleDB ";
//此句一开始提示有转义错误,是因为Data Source中有一个\,在前面再加了个\这样就OK了
//其中Data Source是打开SQL Server时,自动显示的服务器名
//Database是需要联系的数据库的名字
SqlConnectionconn =newSqlConnection(strString);
stringtableName="Address";
stringquery="Select * from "+tableName;
SqlCommandcmd=newSqlCommand(query,conn);
try
{
conn.Open();
//SqlConnection.State可判断现在连接状态
if(conn.State ==ConnectionState.Open)
{
Console.WriteLine("OK");
}
//创建SqlDataReader对象时,不能像其他对象一样new出来,只能使用SqlCommand.ExecuteReader()方法来获得
SqlDataReaderreader = cmd.ExecuteReader();
//SqlDataReader在使用前,必须加载行,运用Read()方法,如果首次调用此方法,会加载第一行,并返回一个bool值,表示是否成功
//所以,一般直接把这个方法放在whiel循环中
//如果在加载前试图读取数据,则会产生InvalidOperationException异常,所以,在试用前也可用SqlDataReader.HasRows属性来判断
while(reader.Read())
{
//sqlDataReader.FieldCount:获取数据阅读器中行的列数,结果为一个int值
//sqlDataReader.GetName();获取指定列的名称
for(intindex = 0; index < reader.FieldCount; index++)
{
//reader[index].ToString()都是用来提取列里面的数据的
Console.WriteLine(reader.GetName(index)+": "+reader[index].ToString()+";");
}
Console.WriteLine();
}
reader.Close();
}
catch(Exceptionex)