String connectionString = "Data Source=DBSERVER;" + "Initial Catalog=AdventureWorlds;IntegratedSecurity=SSPI;" + "MultipleActiveResultSets=True"; |
它的默认设定是"False",并且你能明确地禁用它-如果你想传递"False"给这个MultipleActiveResultSets设定的话。
请遵循下面步骤来建立和启动MARS和ADO.NET 2.0:
1. 创建一个如上面所示的连接字符串。
2. 创建一个SqlConnection对象并且用该连接字符串初始化它。
3. 使用它的Open()方法打开这个SqlConnection对象。
4. 对于你想要执行的每个查询,创建一个新的SqlCommand对象。把它们与你在上面创建并打开的SqlConnection对象相关联。
5. 使用适当的命令(如,如果你想读该取查询结果的话,可以使用ExecuteReader();或使用ExecuteNonQuery()来进行更新,等等)来执行查询。
6. 完成后,关闭SqlConnection对象。
二、实战
在实际开发中普遍存在的一种典型的从数据库中读写数据的情形是,你可以使用多重连接而现在只用一个连接就足够了。例如,如果你有一些来自于几个表中的数据-它们不能被联结到一个查询中,那么你就会有多重的连接-每个连接都有一个与之相关连的命令用于读取数据。同样,如果你正在向一个表写数据,那么你需要另外一个连接或连接集合-如果有多个表要被更新的话。
可以考虑这样的情形-你需要读取来自两个查询A和B中的数据-从可能要写向表C的数据获取值,并且对你要写向表D的行为保持一个审计记录。在如此情形中,你的代码可能如下:
·为A打开一个连接
·执行查询A,并且填充一个数据集
·为A关闭一个连接
·为B打开一个连接
·执行查询B,并且填充一个数据集
·为B关闭一个连接
·为C打开一个连接
·为D打开一个连接
·用从A和B中取得的详细数据更新C
·用做过的审计标记更新D
·关闭D
·关闭C
这是相当复杂的!
当使用MARS时,你只要完成如下:
·用"MultipleActiveResultSets=true"打开连接
·执行A并且填充一个数据集
·执行B并且填充一个数据集
·用从A和B中取得的详细数据更新C
·用做过的审计标记更新D
·关闭连接
更简单!
三、基于MARS和C#的示例分析
本示例使用了随同SQL Server 2005一起发行的AdventureWorks示例数据库,并且使用了该数据库的开发版。注意,它还要改变该库的一些字段的内容,因此如果你想把这个示例数据库用于别的目的,请注意这一点。
本示例将展示怎样从数据库中读取一个SalesOrder,然后减少已卖出的项目的库存数额。典型地,这将要求建立到数据库的两个顺序连接-一个用于读取售出的项目数额,另一个用于使用减少的数额来更新库存。
下面的代码片断显示了怎样在不使用MARS功能的情况下达到这一目的。
ArrayList ids = new ArrayList(); ArrayList qtys = new ArrayList(); string connectionString = "Data Source=MEDIACENTER;" + "Initial Catalog=AdventureWorks;Integrated Security=SSPI;" + "MultipleActiveResultSets=False"; string strSQLGetOrder = "Select * from Sales.SalesOrderDetail" + "WHERE SalesOrderID = 43659"; SqlConnection readConnection = new SqlConnection(connectionString); readConnection.Open(); SqlCommand readCommand =new SqlCommand(strSQLGetOrder, readConnection); using (SqlDataReader rdr = readCommand.ExecuteReader()){ while (rdr.Read()){ ids.Add(rdr["ProductID"]); qtys.Add(rdr["OrderQty"]); } } readConnection.Close(); string strSQLUpdateInv = "UPDATE Production.ProductInventory " + "SET Quantity=Quantity-@amt WHERE (ProductID=@pid)"; SqlConnection writeConnection = new SqlConnection(connectionString); writeConnection.Open(); SqlCommand writeCommand = new SqlCommand(strSQLUpdateInv,writeConnection); writeCommand.Parameters.Add("@amt",SqlDbType.Int); writeCommand.Parameters.Add("@pid",SqlDbType.Int); for(int lp=0;lp<ids.Count;lp++){ writeCommand.Parameters["@amt"].Value=qtys[lp]; writeCommand.Parameters["@pid"].Value=ids[lp]; writeCommand.ExecuteNonQuery(); } writeConnection.Close(); |
string connectionString = "Data Source=MEDIACENTER;" + "Initial Catalog=AdventureWorks;Integrated Security=SSPI;" + "MultipleActiveResultSets=True"; string strSQLGetOrder = "Select * from Sales.SalesOrderDetail" + "WHERE SalesOrderID = 43659"; string strSQLUpdateInv = "UPDATE Production.ProductInventory " + "SET Quantity=Quantity-@amt WHERE (ProductID=@pid)"; SqlConnection marsConnection = new SqlConnection(connectionString); marsConnection.Open(); SqlCommand readCommand = new SqlCommand(strSQLGetOrder, marsConnection); SqlCommand writeCommand = new SqlCommand(strSQLUpdateInv, marsConnection); writeCommand.Parameters.Add("@amt", SqlDbType.Int); writeCommand.Parameters.Add("@pid", SqlDbType.Int); using (SqlDataReader rdr = readCommand.ExecuteReader()){ while (rdr.Read()){ writeCommand.Parameters["@amt"].Value = rdr["OrderQty"]; writeCommand.Parameters["@pid"].Value = rdr["ProductID"]; writeCommand.ExecuteNonQuery(); } } marsConnection.Close(); |