通过ADO.NET技术,我们可以高效的完成客户端同数据库之间的数据访问操作,便于我们在客户端程序简便高效的访问以及获取数据库中的有用数据,同时也可以对数据库中的数据进行更新,即可以完成客户端与数据库之间的双向操作。

本文简单介绍如何在客户端程序中利用ADO.NET 技术来访问以及使用数据库中的数据。

ADO.NET对象模型的最主要的4个组成部分分别是:Connection(SQLConnection)、Command(SQLCommand)、DataReader(SQLDataReader),DataAdapter(SQLDataAdapter)。

下面我们将详细介绍这四种对象的基本用法和其常用的属性、方法以及如何利用它们来完成对数据库的访问操作。

1、Connection(SQLConnection)

Connection对象位于最顶层,是所有数据访问请求的关口。简单来说,我们访问数据库中的数据的一般流程为:连接目标数据库-->访问执行命令(如结构化查询语言命令)-->返回命令执行结果并进行处理-->关闭连接,而Connection对象就用于流程的第一步:

连接目标数据库(即连接数据源)

我们先看一下以下简单实例:

  1. using System;
  2. using System.Data.SqlClient;
  3. namespace Test
  4. {
  5. class Program
  6. {
  7. static void Main(string[] args)
  8. {
  9. SqlConnection mSqlConnection=new SqlConnection();
  10. mSqlConnection.ConnectionString="Data Source=SQLServerInstanceName;Initial Catalog=DBName;Integrated Security=SSPI;";
  11. mSqlConnection.Open();
  12. if(mSqlConnection.State==System.Data.ConnectionState.Open)
  13. {
  14. Console.WriteLine("Database Connection is Open");
  15. }
  16. mSqlConnection.Close();
  17. }
  18. }
  19. }

  首先,为了能够使用SQLConnection类,我们首先需要引用命名空间System.Data.SqlClient(using System.Data.SqlClient);接着创建SQLConnection类型的实例对象

mSqlConnection,为其属性ConnectionString赋值连接字符串;然后调用Open()方法,这就完成了数据库的连接操作;最后记得在完成访问数据操作之后,调用Close()方法,关闭连接。

Connection对象具有多个属性以及方法,下面介绍最基础常用的属性以及方法:

常用属性:

ConnectionString:获取或设置用来打开SQLServer数据库的连接字符串

ConnectionTimeout:获取等待时间,即终止尝试连接操作或者返回错误信息之前的等待时间。

DataSource:获取要连接的SQL Server实例名称。

Database:获取数据库的名称。

常用方法:

Open():使用COnnectionString中指定的属性设置数据库连接。

Close():关闭数据库连接。

我们在连接字符串中可以看到设置了Data Source、InitialCatalog以及Integrated Security三个值:Data Source表示要连接的SQL Server实例名称;Initial Catalog表示要访问的数据库名称;

Integrated Security表示所采用的安全验证方式。

Integrated Security设置为SSPI或者true,则表示采用Windows身份验证;否则表示采用SQL Server身份验证,此时就需要在连接字符串中设置User ID和Password

连接字符串的设置

连接字符串既可以在ConnectionString属性中设置,也可以在创建SqlConnection实例对象时设置,还可以在配置文件中设置:

  1. using System;
  2. using System.Data.SqlClient;
  3. using System.Configuration;
  4. namespace Test
  5. {
  6. class Program
  7. {
  8. static void Main(string[] args)
  9. {
  10. //1.ConnectionString属性设置
  11. SqlConnection mSqlConnection=new SqlConnection();
  12. mSqlConnection.ConnectionString="Data Source=SQLServerInstanceName;Initial Catalog=DBName;Integrated Security=SSPI;";
  13. //2.创建对象实例时设置
  14. string connectionString1="Data Source=SQLServerInstanceName;Initial Catalog=DBName;Integrated Security=SSPI;";
  15. SqlConnection mSqlConnection1=new SqlConnection(connectionString1);
  16. //3、配置文件中设置
  17. string connectionString2=ConfigurationManager.AppSettings["ConnectionString"].ToString();
  18. SqlConnection mSqlConnection2=new SqlConnection(connectionString2);
  19. }
  20. }
  21. }

配置文件如下:

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3. <appSettings>
  4. <add key="ConnectionString" value="Data Source=SQLServerInstanceName;Initial Catalog=DBName;Integrated Security=SSPI;"/>
  5. </appSettings>
  6. <startup>
  7. <supportedRuntime version="v4.0" sku=".NETFramework,Version=4.5"/>
  8. </startup>
  9. </configuration>

注意:获取配置文件中的连接字符串时首先需要引用System.Configuration(using System.Configuration

资源释放以及异常处理

数据库的连接操作时十分占用资源的,在使用完成之后一定要关闭连接,释放资源。一般调用Close()方法关闭连接,释放资源。但有时我们会忘记调用Close()方法,这就导致了资源的浪费。为了避免这种情况的发生,我们可以使用using来完成资源的释放。而对于异常处理,我们可以使用try{...}catch(...){...}操作,示例代码如下所示:

  1. try
  2. {
  3. string connectionString=configurationManager.AppSettings["ConnectionString"].ToString();
  4. using (SqlConnection mSqlConnection =new SqlConnection(connectionString))
  5. {
  6. mSqlConnection.Open();
  7. if(mSqlConnection.State==ConnectionState.Open)
  8. {
  9. Console.WriteLine("Database Connection is Open");
  10. }
  11. }}
  12. catch(SqlException e)
  13. {
  14. Console.WriteLine(e.Message);
  15. }
  16. catch(Exception ex)
  17. {
  18. Console.WriteLine(ex.Message);
  19. }
    SQLConnection实例对象mSqlConnection相关操作的进一步封装
    我们可以将对mSqlConnection 的相关操作进一步提取封装到一个方法中,这样有利于代码的重用,示例如下所示:
    注意:下面的代码中我们将使用SQLConnectionStringBuilder对象来创建连接字符串
  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. try
  6. {
  7. using (SqlConnection mSqlConnection=GetSqlConnection("SQLServerInstanceName","DatabaseName","","",true)){
  8. if(mSqlConnection.State==ConnectionState.Open)
  9. {
  10. Console.WriteLine("Database Connection is Open");
  11. }
  12. }
  13. }
  14. catch(SqlException e)
  15. {
  16. Console.WriteLine(e.Message);
  17. }
  18. catch(Exception ex)
  19. {
  20. Console.WriteLine(ex.Message);
  21. }
  22. }
  23. public static SqlConnection GetSqlConnection(string server,string database,string userid,string password,bool integratedSecurity)
  24. {
  25. SqlConnection mSqlConnection =new SqlConnection();
  26. mSqlConnection.ConnectionString=GetSqlConnectionString(server,database,userid,password,integratedSecurity);
  27. mSqlConnection.Open();
  28. return mSqlConnection;
  29. }
  30. public static string GetSqlConnectionString(string server,string database,string username,string password,bool ignoredUserId)
  31. {
  32. SqlConnectionStringBuilder mSqlConnectionStringBuilder=new SqlConnectionStringBuilder();
  33. mSqlConnectionStringBuilder.DataSource=server;
  34. mSqlConnectionStringBuilder.InitialCatalog=database;
  35. if(!ignoredUserId && !string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))
  36. {
  37. mSqlConnectionStringBuilder.IntegratedSecurity=false;
  38. mSqlConnectionStringBuilder.UserID=username;
  39. mSqlConnectionStringBuilder.Password=password;}
  40. else{
  41. mSqlConnectionStringBuilder.IntegratedSecurity=true;
  42. }
  43. return mSqlConnectionStringBuilder.ConnectionString;
  44. }
  45. }}
  1.  

2、Command(SQLCommand)

当成功连接到数据库之后,接下来我们就要进行数据的访问操作了,比如对数据源的查询操作等,这时就需要使用Command对象了。

SQLCommand类最基本常用的属性和方法如下所示(其他的不在这里列举,读者可自行查询)

方法:

ExecuteNonQuery():用于执行SQL语句,该方法用于不需要返回任何记录的情况(例如,INSERT,DELETE或UPDATE查询)

ExecuteReader():用于执行SQL语句并返回一组数据。

ExecuteScalar():用于执行查询,并返回查询所返回的结果集中第一行第一列的内容,其他内容将被忽略。

ExecuteXmlReader():以XmlReader 形式返回结果集。

属性:

CommandText:设置对数据源执行的文本命令

CommandTimeout:等待时间

CommandType:对CommandText属性的解释(枚举,其中包括StoredProcedure、TableDirect和Text)

Connection:数据库连接。

Parameters:Parameter对象的集合

ExecuteReader()方法

示例1:

  1. int rowCount=;
  2. try{
  3. using (SqlConnection mSqlConnection =GetSqlConnection("SQLServerInstanceName","DatabaseName","","",true))
  4. {
  5. if(mSqlConnection.State==ConnectionState.Open)
  6. {
  7. Console.WriteLine("Database Connection is Open");
  8. }
  9. using (SqlCommand mSqlCommand=new SqlCommand())
  10. {
  11. mSqlCommand.Connection=mSqlConnection;
  12. mSqlCommand.CommandText="SELECT productId,productName,productDescription FROM product";
  13. mSqlCommand.CommandType=CommandType.Text;
  14. using(SqlDataReader mSqlDataReader=mSqlCommand.ExecuteReader())
  15. {
  16. while(mSqlDataReader.Read())
  17. {
  18. rowCount++;
  19. }
  20. }
  21. }}
  22. }
  23. catch(SqlException e)
  24. {
  25. Console.WriteLine(e.Message);
  26. }
  27. catch(Exception ex)
  28. {
  29. Console.WriteLine(ex.Message);
  30. }

调用ExecuteReader()方法将返回的结构集存储在SqlDataReader的对象实例mSqlDataReader中,通过对mSqlDataReader进行一系列操作,我们就可以获取到返回结果集中的详细数据了。

注意:在使用完mSqlDataReader之后,一定记得释放资源

ExecuteScalar()方法

示例2:

  1. int totalCount=;
  2. try
  3. {
  4. using(SqlConnection mSqlConnection=GetSqlConnection("SQLServerInstanceName","DatabaseName","","",true))
  5. {
  6. if(mSqlConnection.State==ConnectionState.Open)
  7. {
  8. Console.WriteLine("Database Connection is Open");
  9. }
  10. using (SqlCommand mSqlCommand=new SqlCommand())
  11. {
  12. mSqlCommand.Connection=mSqlConnection;
  13. mSqlCommand.CommandText=string.Format("select count(*)from webs with (nolock) where DeleteTransactionId=0x");
  14. mSqlCommand.COmmndType=CommandType.Text;
  15. object result=mSqlCommand.ExecuteScalar();
  16. if(result !=null)
  17. {
  18. totalCount=Convert.ToInt32(result);
  19. }
  20. }
  21. }
  22. }
  23. catch(SqlException e)
  24. {
  25. Console.WriteLine(e.Message);
  26. }
  27. catch(Exception ex)
  28. {
  29. Console.WriteLineex.Message);
  30. }

ExecuteScalar()方法返回结果集中第一行第一列的内容,其返回值类型为object

3、DataReader(SQLDataReader)

DataReader用于从数据源获取只读且只进的数据集。DataReader是在查询的过程中获取数据,而不是等待查询结束。

DataReader通过Command对象的ExecuteReader() 方法获得,我们通过演示删除DB的物理文件的操作来展示如何运用DataReader:

代码示例如下:

  1. class Program
  2. {
  3. private static readonly string mDefaultDatabase = "master";
  4.  
  5. static void Main(string[] args)
  6. {
  7. try
  8. {
  9. Console.WriteLine("请输入SQL Server实例名称和要删除的DB Name:");
  10. string serverInstanceName = Console.ReadLine();
  11. string dbName = Console.ReadLine();
  12. bool integratedSecurity = true;
  13. string userId = "";
  14. string password = "";
  15. if (string.IsNullOrEmpty(serverInstanceName) || string.IsNullOrEmpty(dbName))
  16. {
  17. Console.WriteLine("SQL Server实例名称和要删除的DB Name均不能为空");
  18. }
  19. else
  20. {
  21. do
  22. {
  23. Console.WriteLine("是否使用Windows身份验证? Y:yse or N:no");
  24. string yes = Console.ReadLine();
  25. if (string.IsNullOrEmpty(yes))
  26. {
  27. Console.WriteLine("请重新选择!");
  28. }
  29. else if(yes.Equals("Yes",StringComparison.OrdinalIgnoreCase)||yes.Equals("Y", StringComparison.OrdinalIgnoreCase))
  30. {
  31. integratedSecurity = true;
  32. break;
  33. }
  34. else if (yes.Equals("No", StringComparison.OrdinalIgnoreCase) || yes.Equals("N", StringComparison.OrdinalIgnoreCase))
  35. {
  36. Console.WriteLine("请输入用户名和密码:");
  37. userId = Console.ReadLine();
  38. password = Console.ReadLine();
  39. integratedSecurity = false;
  40. break;
  41. }
  42. else
  43. {
  44. Console.WriteLine("请重新选择!");
  45. }
  46. }
  47. while (true);
  48.  
  49. if (DeleteDbByName(serverInstanceName, dbName, userId, password, integratedSecurity))
  50. {
  51. Console.WriteLine("Delete database {0} successfully.", dbName);
  52. }
  53.  
  54. }
  55. }
  56. catch (Exception e)
  57. {
  58. Console.WriteLine(e.ToString());
  59. }
  60. }
  61.  
  62. public static bool DeleteDbByName(string serverInstanceName, string dbName, string userName, string password, bool isIntegrateSecurity)
  63. {
  64. bool isNull = false;
  65. for (int i = ; i < ; i++)
  66. {
  67. try
  68. {
  69. isNull = CheckDBIsNull(serverInstanceName, dbName, userName, password, isIntegrateSecurity);
  70. break;
  71. }
  72. catch (Exception e)
  73. {
  74. if (i == )
  75. {
  76. throw new Exception("Database is null. 5 times retrying failed.");
  77. }
  78. }
  79. Thread.Sleep();
  80. }
  81. if (isNull)
  82. {
  83. return true;
  84. }
  85. string physicalDB = "";
  86. string physicalLog = "";
  87. GetDBPhysicalFilePath(serverInstanceName, dbName, userName, password, isIntegrateSecurity, ref physicalDB, ref physicalLog);
  88. DeleteDBPhysicalFilePath(serverInstanceName, dbName, userName, password, isIntegrateSecurity, physicalDB, physicalLog);
  89. return true;
  90. }
  91.  
  92. public static SqlConnection GetSqlConnection(string serverInstance, string dbName, string userName, string password, bool integratedSecurity)
  93. {
  94. SqlConnection mSqlConnection = new SqlConnection();
  95. mSqlConnection.ConnectionString = GetSqlConnectionString(serverInstance, dbName, userName, password, integratedSecurity);
  96. mSqlConnection.Open();
  97. return mSqlConnection;
  98. }
  99.  
  100. public static string GetSqlConnectionString(string serverInstance, string dbName, string userName, string password, bool integratedSecurity)
  101. {
  102. SqlConnectionStringBuilder mSqlConnectionStringBuilder = new SqlConnectionStringBuilder();
  103. mSqlConnectionStringBuilder.DataSource = serverInstance;
  104. if (string.IsNullOrEmpty(dbName))
  105. {
  106. mSqlConnectionStringBuilder.InitialCatalog = mDefaultDatabase;
  107. }
  108. else
  109. {
  110. mSqlConnectionStringBuilder.InitialCatalog = dbName;
  111. }
  112. if (!integratedSecurity && !string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password))
  113. {
  114. mSqlConnectionStringBuilder.IntegratedSecurity = false;
  115. mSqlConnectionStringBuilder.UserID = userName;
  116. mSqlConnectionStringBuilder.Password = password;
  117. }
  118. else
  119. {
  120. mSqlConnectionStringBuilder.IntegratedSecurity = true;
  121. }
  122. return mSqlConnectionStringBuilder.ConnectionString;
  123. }
  124.  
  125. public static bool CheckDBIsNull(string serverInstance, string dbName, string userName, string password, bool integratedSecurity)
  126. {
  127. bool dbIsNull = false;
  128. using (SqlConnection sqlConn = GetSqlConnection(serverInstance, "", userName, password, integratedSecurity))
  129. {
  130. using (SqlCommand sqlCmd = new SqlCommand("master.dbo.xp_msver"))
  131. {
  132. sqlCmd.Connection = sqlConn;
  133. string text = "USE master SELECT * FROM sysdatabases WHERE name = N'" + dbName + "'";
  134. sqlCmd.CommandText = text;
  135. sqlCmd.ExecuteNonQuery();
  136. if (sqlCmd.ExecuteScalar() == null)
  137. {
  138. dbIsNull = true;
  139. }
  140. }
  141. }
  142. return dbIsNull;
  143. }
  144.  
  145. public static void GetDBPhysicalFilePath(string serverInstance, string dbName, string userName, string password, bool integratedSecurity, ref string physicalDB, ref string physicalLog)
  146. {
  147. string physicalPath = string.Empty;
  148. using (SqlConnection sqlConn = GetSqlConnection(serverInstance, "", userName, password, integratedSecurity))
  149. {
  150. if (GetDBStatus(sqlConn, dbName) == SQLDatabaseStatus.ONLINE)
  151. {
  152. using (SqlCommand sqlCmd = new SqlCommand("master.dbo.xp_msver"))
  153. {
  154. sqlCmd.Connection = sqlConn;
  155. sqlCmd.CommandText = string.Format("use {0} exec sp_helpfile", dbName);
  156. using (SqlDataReader sqlReader = sqlCmd.ExecuteReader())
  157. {
  158. while (sqlReader.Read())
  159. {
  160. physicalPath = sqlReader.GetValue().ToString().TrimEnd("".ToCharArray());
  161. if (physicalPath.ToLower(CultureInfo.InvariantCulture).Contains(".mdf"))
  162. {
  163. physicalDB = physicalPath;
  164. }
  165. else
  166. {
  167. physicalLog = physicalPath;
  168. }
  169. }
  170. }
  171. }
  172. }
  173. }
  174. }
  175.  
  176. public static void DeleteDBPhysicalFilePath(string serverInstance, string dbName, string userName, string password, bool integratedSecurity, string physicalDB, string physicalLog)
  177. {
  178. using (SqlConnection sqlConn = GetSqlConnection(serverInstance, "", userName, password, integratedSecurity))
  179. {
  180. using (SqlCommand sqlCmd = new SqlCommand("master.dbo.xp_msver"))
  181. {
  182. sqlCmd.Connection = sqlConn;
  183. string text = string.Empty;
  184. sqlCmd.CommandText = string.Empty;
  185. sqlCmd.CommandText = GetEndDBProcessCommand(dbName);
  186. for (int i = ; i < ; i++)
  187. {
  188. try
  189. {
  190. sqlCmd.ExecuteNonQuery();
  191. break;
  192. }
  193. catch (Exception e)
  194. {
  195. Console.WriteLine(string.Format("Stopping all process for {0} {1} failed, {2}.", serverInstance, dbName, e.ToString()));
  196. }
  197. Thread.Sleep();
  198. }
  199. sqlCmd.CommandText = string.Format("drop database {0}", dbName);
  200. try
  201. {
  202. sqlCmd.ExecuteNonQuery();
  203. }
  204. catch (Exception e)
  205. {
  206. throw new Exception(string.Format("Failed to drop temp database {0} {1}", serverInstance, dbName));
  207. }
  208. try
  209. {
  210. if (File.Exists(physicalDB))
  211. {
  212. File.Delete(physicalDB);
  213. }
  214. if (File.Exists(physicalLog))
  215. {
  216. File.Delete(physicalLog);
  217. }
  218. }
  219. catch (Exception e)
  220. {
  221. Console.WriteLine(string.Format("An error occurred while deleting database {0} {1}, {2}.", serverInstance, dbName, e.ToString()));
  222. }
  223. }
  224. }
  225. }
  226.  
  227. public static string GetEndDBProcessCommand(string dbName)
  228. {
  229. string killpc = "declare @spid varchar(20) \n" +
  230. "declare #spid cursor for \n" +
  231. "select spid=cast(spid as varchar(20)) from master..sysprocesses where dbid=db_id(N'" +
  232. dbName + "') and spid>50\n" +
  233. "open #spid \n" +
  234. "fetch next from #spid into @spid \n" +
  235. "while @@fetch_status=0 \n" +
  236. "begin \n" +
  237. " exec('kill '+@spid) \n" +
  238. " fetch next from #spid into @spid \n" +
  239. "end \n" +
  240. "close #spid \n" +
  241. "deallocate #spid";
  242. return killpc;
  243. }
  244.  
  245. public static SQLDatabaseStatus GetDBStatus(SqlConnection conn, string dbName)
  246. {
  247. using (SqlCommand cmd = conn.CreateCommand())
  248. {
  249. cmd.CommandText = "SELECT DATABASEPROPERTYEX(@dbName, 'Status')";
  250. cmd.Parameters.Add("@dbName", SqlDbType.NText).Value = dbName;
  251. string statusString = null;
  252. using (SqlDataReader reader = cmd.ExecuteReader())
  253. {
  254. if (reader.Read())
  255. {
  256. statusString = reader[].ToString();
  257. }
  258. }
  259. foreach (SQLDatabaseStatus status in Enum.GetValues(typeof(SQLDatabaseStatus)))
  260. {
  261. if (status.ToString().Equals(statusString, StringComparison.OrdinalIgnoreCase))
  262. {
  263. return status;
  264. }
  265. }
  266. }
  267. throw new Exception(string.Format("Cannot get status of database {0} on server {1}", dbName, conn.DataSource));
  268. }
  269.  
  270. public enum SQLDatabaseStatus
  271. {
  272. /// <summary>
  273. /// Database is available for query.
  274. /// </summary>
  275. ONLINE = ,
  276. /// <summary>
  277. /// Database was explicitly taken offline.
  278. /// </summary>
  279. OFFLINE = ,
  280. /// <summary>
  281. /// Database is being restored.
  282. /// </summary>
  283. RESTORING = ,
  284. /// <summary>
  285. /// Database is recovering and not yet ready for queries.
  286. /// </summary>
  287. RECOVERING = ,
  288. /// <summary>
  289. /// Database did not recover.
  290. /// </summary>
  291. SUSPECT = ,
  292. /// <summary>
  293. /// Database is in an emergency, read-only state. Access is restricted to sysadmin members
  294. /// </summary>
  295. EMERGENCY =
  296. }
  297. }
  1. 除此之外我们还需要注意的一点是DataReader提供了对多结果集的支持,如果返回多个结果集,则应使用DataReaderNextResult方法。该方法将按照顺序对返回的结果集进行迭代,
    代码示例如下:
  1. try
  2. {
  3. using (SqlConnection mSqlConnection = GetSqlConnection("SQLServerInstanceName", "DatabaseName", "", "", true))
  4. {
  5. if (mSqlConnection.State == ConnectionState.Open)
  6. {
  7. Console.WriteLine("Database Connection is Open");
  8. }
  9. using (SqlCommand mSqlCommand = mSqlConnection.CreateCommand())
  10. {
  11. mSqlCommand.CommandText = "SELECT productId, productName, productDescription FROM product";
  12. mSqlCommand.CommandType = CommandType.Text;
  13. using (SqlDataReader mSqlDataReader = mSqlCommand.ExecuteReader())
  14. {
  15. string outputRow = "";
  16. if (mSqlDataReader.HasRows)
  17. {
  18. bool mHasMoreResults = true;
  19. while (mHasMoreResults)
  20. {
  21. while (mSqlDataReader.Read())
  22. {
  23. outputRow = string.Format("{0}, {1}, {2}", mSqlDataReader.GetString(0), mSqlDataReader.GetString(1), mSqlDataReader.GetString(2));
  24. }
  25. mHasMoreResults = mSqlDataReader.NextResult();
  26. }
  27. }
  28. }
  29. }
  30. }
  31. }
  32. catch (SqlException e)
  33. {
  34. Console.WriteLine(e.Message);
  35. }
  36. catch (Exception ex)
  37. {
  38. Console.WriteLine(ex.Message);
  39. }
  1.  
  1.  

4.DataAdapter(SqlDataAdapter)

  1.  

DataAdapter是客户端的DataSet与数据源之间的桥梁。我们可以通过使用它来获取、插入、更新和删除数据。而根据数据方向的不同,可以使用Fill来使DataAdapter更改DataSet的数据,来保持同数据源的数据一致;使用Update可以使DataAdapter更新数据源中的数据,使数据源中的数据和DataSet保持一致。

  1.  

客户端的DataSet <——(Fill方法) DataAdapter(Update 方法) ——> 数据源

  1.  
  1.  

5.数据集 DataSet

  1.  

数据集DataSet允许我们以关系方式表示数据。虽然在默认情况下DataSet与数据库无关,但是我们也可以在需要的时候使用针对特定数据库的功能。

  1.  

在ADO.NET中,DataSet对象主要用于支持非连接的、分布式的数据。DataSet是一种驻留于内存的数据表示,不论使用哪种数据源,它都能提供一致的关系编程模型。DataSet可以与多个不同的数据源以及XML数据配合使用,也可以用来管理应用程序自身的数据。

  1.  

DataSet代表完整的数据集合,其中包括关联的表、约束和表间的关系。

  1.  

DataSet类的层次结构:

  1.  

5.1 DataSet

  1.  

DataSet是对象树的根,代表数据的内存缓存,包含表以及表的关系。

  1.  

DataSet类的常用属性以及方法如下两表所示:

  1.  

构造DataSet代码:

  1.  
  1. public static DataSet BuildDataSet()
  2. {
  3. //创建DataSet
  4. DataSet ds = new DataSet();
  5. try
  6. {
  7. //创建DataTable,其有列和行组成
  8. DataTable dt = new DataTable("StudentInfo");
  9.  
  10. //定义列
  11. DataColumn[] dc = new DataColumn[7];
  12. dc[0] = new DataColumn("StudentID", typeof(int));
  13. dc[1] = new DataColumn("StudentName", typeof(string));
  14. dc[2] = new DataColumn("StudentSex", typeof(string));
  15. dc[3] = new DataColumn("StudentClass", typeof(int));
  16. dc[4] = new DataColumn("StudentBirth", typeof(string));
  17. dc[5] = new DataColumn("StudentPhoneNumber", typeof(string));
  18. dc[6] = new DataColumn("StudentAddress", typeof(string));
  19. dt.Columns.AddRange(dc);
  20.  
  21. //为表设置主键 StudentID
  22. dt.PrimaryKey = new DataColumn[] { dc[0] };
  23. //为表设置完整性约束--唯一性约束 StudentName 主键的设置和唯一性约束不能相同,否则会出现重复
  24. dt.Constraints.Add(new UniqueConstraint(dc[1]));
  25.  
  26. //设置行
  27. dt.Rows.Add(new object[] { 101, "王国强", "男", 101, "1992年5月18日", "13990824456", "东1舍423" });
  28. dt.Rows.Add(new object[] { 102, "张丽华", "女", 101, "1991年10月25日", "13846725530", "东2舍301" });
  29. dt.Rows.Add(new object[] { 103, "孙美美", "女", 102, "1992年3月23日", "13456890034", "东2舍402" });
  30.  
  31. //主键具有唯一性,因此StudentID不能相同,否则会报错
  32. //dt.Rows.Add(new object[] { 101, "孙美美", "女", 102, "1992年3月23日", "13456890034", "东2舍402" });
  33.  
  34. //StudentName设置了唯一性约束,因此不能出现重复值,否则报错
  35. //dt.Rows.Add(new object[] { 104, "孙美美", "女", 102, "1992年3月23日", "13456890034", "东2舍402" });
  36. ds.Tables.Add(dt);
  37. }
  38. catch (Exception ex)
  39. {
  40. Console.WriteLine(ex.Message);
  41. }
  42. return ds;
  43. }
  1.  

5.2 DataTable

  1.  

DataTable代表内存中的数据表。如果要在代码中创建DataTable,则首先需要使用DataColumnCollection添加列Column来定义表的结构。而在表中添加行row,需要使用DataTable的NewRow方法来创建新的DataRow对象。除此之外,DataTable还包含一个Constraint对象的集合,用来确保数据的完整性。

  1.  

DataTable的常用属性以及方法如下两表所示:

  1.  

5.3 DataRow

  1.  

行和列用于在DataTable中存储数据。DataRow对象提供了选定列的字典式的访问方式,其存储各列的值。同时,行也可以存储从数据库中获取的数据,也可以用于插入、删除以及更新DataTable中的值。

  1.  

5.4 DataColumn

  1.  

DataColumn用于定义表中的列。DataColumn的DataType属性可以用来定义列的数据类型。

  1.  

AllowDBNull、Unqiue以及ReadOnly属性可以对数据项添加约束,并对数据进行更新,有助于确保数据的完整性。

  1.  

同时,其的AutoIncrement、AutoIncrementSeed以及AutoIncrementStep属性可以来控制值的自动生成。

  1.  

最后,我们可以通过DataColumn中的Expression属性来计算列中的值或者来创建聚合列。

  1.  

创建DataColumn和DataRow的示例如下所示:

  1.  
  1. DataSet ds = new DataSet();
  2. DataTable dt = new DataTable("Students");
  3. DataColumn dc1 = new DataColumn("StudentName", typeof(string));
  4. DataColumn dc2 = new DataColumn("StudentID", typeof(int));
  5. dt.Columns.Add(dc1);
  6. dt.Columns.Add(dc2);
  7.  
  8. DataRow dr1 = dt.NewRow();
  9. dr1["StudentName"] = "雄霸";
  10. dr1["StudentID"] = 101;
  11. dt.Rows.Add(dr1);
  12.  
  13. DataRow dr2 = dt.NewRow();
  14. dr2[dc1] = "聂风";
  15. dr2[dc2] = 102;
  16. dt.Rows.Add(dr2);
  17.  
  18. DataRow dr3 = dt.NewRow();
  19. dr3[0] = "步惊云";
  20. dr3[1] = 103;
  21. dt.Rows.Add(dr3);
  22. ds.Tables.Add(dt);
  1.  

5.5 DataView

  1.  

同数据库一样,DataView用于在DataTable上创建视图,允许视图中的数据作为DataTable中数据的子集,同时,还可以进行不同方式的排序。

  1.  

5.6 从数据库中读取数据

  1.  

数据适配器DataAdapter 用来从数据库中读取数据,并将数据填充到DataSet以及DataTable中;同时,DataSet和DataTable还可以将数据写回到数据库中,完成数据库中数据的更新。

  1.  

使用DataAdapter获取数据库数据的流程:连接数据库(连接数据源) —> 获取数据库中的数据 —> 使用DataAdapter填充到DataSet和DataTable中。

  1.  

代码示例如下所示:

  1.  
  1. try
  2. {
  3. DataSet ds = new DataSet();
  4. //连接数据库获取数据,填充到DataSet中
  5. using (SqlConnection sqlConnection = new SqlConnection(@"Data Source =.;Initial Catalog = StudentInfomation;Integrated Security = True"))
  6. {
  7. using (SqlCommand sqlCommand = new SqlCommand("select * from Students", sqlConnection))
  8. {
  9. using (SqlDataAdapter adapter = new SqlDataAdapter(sqlCommand))
  10. {
  11. adapter.Fill(ds, "Students");
  12. adapter.FillSchema(ds, SchemaType.Source, "Students");
  13. }
  14. }
  15. }
  16. }
  17. catch (Exception ex)
  18. {
  19. Console.WriteLine(ex.Message);
  20. }
  1.  

5.7 DataSet数据类型

  1.  

DataSet位于命名空间System.Data中,且与数据库无关。我们将数据从数据库加载到DataSet中后,数据源便会脱离,无法通过DataSet进行操作。

  1.  

FillSchema:如果将ReturnProviderSpecificTypes设置为true,则就不能再使用FillSchema。

  1.  
 
  1.  
分类: ADO.NET
  1.  

ADO.NET基础知识学习(SQLCOnnection&SQLCommand&SQLDataReader&SQLDataAdapter&DataSet)的更多相关文章

  1. 【ADO.NET基础知识】SqlConnection、command、DataSet 、DataTable、dataAdapter

    1.使用Connection连接数据库的步骤: (1).添加命名空间 System.Data.SqlClient(注意:初学者经常会忘记) (2)定义连接字符串.连接SQL Server 数据库时: ...

  2. GCC基础知识学习

    GCC基础知识学习 一.GCC编译选项解析 常用编译选项 命令格式:gcc [选项] [文件名] -E:仅执行编译预处理: -S:将C代码转换为汇编代码: -c:仅执行编译操作,不进行连接操作: -o ...

  3. (转)Linux基础知识学习

    Linux基础知识学习 原文:http://blog.csdn.net/ye_wei_yang/article/details/52777499 一.Linux的磁盘分区及目录 Linux的配置是通过 ...

  4. Objective-c基础知识学习笔记

    Objective-c基础知识学习笔记(一) 一直有记录笔记的习惯.但非常久没分享一些东西了,正好上半年開始学习IOS了,如今有空写点.因开发须要,公司特意为我们配置了几台新MAC.还让我们自学了2周 ...

  5. AXAJ基础知识学习

    AXAJ基础知识学习 博客首页 Ajax简介 ajxa全称是Asynchronous Javascript And XML ,就是异步的JS 和XML 通过Ajax可以再浏览器中向服务器发送异步请求, ...

  6. Vue2基础知识学习

    Vue2基础知识学习 01.初识 new Vue({ el: '#root', //用于指定当前Vue实例为哪个容器服务,值通常为css选择器符 data () { return { } } }); ...

  7. Linq的简介和基础知识学习

    学习LINQ之前,我们要知道LINQ是干什么,解决什么问题的,怎样学习? 一.LINQ简介 1.什么是LINQ? 什么是LINQ?LINQ中文翻译为语言集成查询(Language Integrated ...

  8. C#基础知识学习

    C#基础知识整理 学习地址:http://blog.csdn.net/column/details/csarp.html

  9. 韩天峰博客 php基础知识学习记录

    http://rango.swoole.com 写好PHP代码真的不容易,给大家几个建议: 慎用全局变量,全局变量不好管理的,会导致你的代码依赖于全局变量,而耦合度太高. 一定不要复制粘贴代码,可重用 ...

随机推荐

  1. windows 下配置浏览器使用 kerberos

    最近 hadoop 一系列软件都给加上了 kerberos 认证,整体来说还算顺利,各组件也都继续正常工作,唯独 storm ui,个天杀的在 windows 上打不开. HTTP ERROR: 40 ...

  2. JNI基础学习

    1.JNI(Java Native Interface): 它允许Java代码和其他语言写的代码进行交互,JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要 ...

  3. Linux环境安装python3

    linux 安装Python3 1.python下载 请在终端输入如下命令: cd /home wget http://cdn.npm.taobao.org/dist/python/3.6.5/Pyt ...

  4. Codeforces 1038E Maximum Matching

    可能写了个假算法 假设定义:含有一个欧拉路的图为类欧拉图 欧拉路的定义:一个无向连通图中,存在一条路径对所有边都遍历且仅遍历一次:判断方法:该连通图中度为奇数的点的个数不能超过2,即为0或者2 题目解 ...

  5. Node 入门<1>

    1. Node   JavaScript web服务器框架,主要特点:事件驱动,异步 I/O,强制不共享任何资源的单线程,单进程系统. 每一个node进程都构成网络应用中的一个节点.          ...

  6. 【kmp算法】hdu4763 Theme Section

    kmp中next数组的含义是:next[i]表示对于s[0]~s[i-1]这个前缀而言,最大相等的前后缀的长度是多少.规定next[0]=-1. 迭代for(int i=next[i];i!=-1;i ...

  7. 【数论】【枚举约数】【欧拉函数】bzoj2705 [SDOI2012]Longge的问题

    ∵∑gcd(i, N)(1<=i <=N) =k1*s(f1)+k2*s(k2)+...+km*s(km) {ki是N的约数,s(ki)是满足gcd(x,N)=ki(1<=x< ...

  8. SSH学习——声明式事物管理(Spring)

    1.什么是事物? 事务是一组操作的执行单元,相对于数据库操作来讲,事务管理的是一组SQL指令,比如增加,修改,删除等,事务的一致性,要求,这个事务内的操作必须全部执行成功,如果在此过程种出现了差错,比 ...

  9. 64945e3dtw1dii6vfdr19j.jpg(PNG 图像,1497x929 像素)

    64945e3dtw1dii6vfdr19j.jpg(PNG 图像,1497x929 像素)

  10. .net 多文件上传

    版权声明:本文为博主原创文章,未经博主允许不得转载. 1.页面 <head runat="server"> <title>上传文件</title> ...