1異步數據訪問
a)支持異步數據編程
b)SqlConnection
– BeginOpen
– EndOpen
c)SqlCommand
– BeginExecuteNonQuery
– BeginExecuteReader
– BeginExecuteXmlReader
– EndExecuteNonQuery
– EndExecuteReader
– EndExecuteXmlReader
代碼如下:(注意字符串連接,Asynchronous Processing=true)

public partial class Form1 : Form { public Form1() { InitializeComponent(); } delegate void PopulateListEventHandler(SqlDataReader reader); SqlConnection conn; SqlCommand comm; private void button2_Click(object sender, EventArgs e) { conn = new SqlConnection(ConfigurationManager.ConnectionStrings["AdventureWorks"].ConnectionString); comm = conn.CreateCommand(); comm.CommandType = CommandType.Text; comm.CommandText = "SELECT Name FROM Production.Product"; conn.Open(); comm.BeginExecuteReader(new AsyncCallback(HandleAsyncCallBack), null); this.label1.Visible = true; this.button2.Enabled = false; } public void HandleAsyncCallBack(IAsyncResult result) { System.Threading.Thread.Sleep(5000); SqlDataReader reader = comm.EndExecuteReader(result); this.Invoke(new PopulateListEventHandler(populateList), reader); } void populateList(SqlDataReader reader) { while (reader.Read()) { this.comboBox2.Items.Add(reader[0]); } reader.Close(); conn.Close(); this.comboBox2.SelectedIndex = 0; this.label1.Visible = false; this.button2.Enabled = true; } }
2.多活動結果集(MARKS)
a)在SQL Server 2005 中支持多活動結果集
b)允許在單個連接上執行多個批處理
c)啟用MARS
string connectionString = "Data Source=MSSQL1;" + "Initial Catalog=AdventureWorks;Integrated Security=SSPI; MultipleActiveResultSets=True";
代碼如下:

public partial class Form1 : Form { public Form1() { InitializeComponent(); } SqlConnection conn; private void listOrdersButton_Click(object sender, EventArgs e) { //Open the connection (if not already open) and retrieve all order headers if (conn.State != ConnectionState.Open) { conn.Open(); } SqlDataReader orderReader; SqlCommand getOrders = new SqlCommand("SELECT SalesOrderID FROM Sales.SalesOrderHeader WHERE SalesOrderID > 70000", conn); orderReader = getOrders.ExecuteReader(); while (orderReader.Read()) { orderListBox.Items.Add(orderReader["SalesOrderID"]); } //Select the first order and display the products it contains orderListBox.SelectedIndex = 0; DisplayProducts(orderListBox.SelectedItem.ToString()); } private void orderListBox_SelectedIndexChanged(object sender, EventArgs e) { DisplayProducts(orderListBox.SelectedItem.ToString()); } private void DisplayProducts(string OrderID) { //Open the connection if it's closed, otherwise just use it if (conn.State != ConnectionState.Open) { conn.Open(); } //Display the products for the selected order SqlDataReader detailReader; SqlCommand getDetails = new SqlCommand("SELECT ProductID FROM Sales.SalesOrderDetail WHERE SalesOrderID = " + OrderID, conn); detailReader = getDetails.ExecuteReader(); detailListBox.Items.Clear(); while (detailReader.Read()) { detailListBox.Items.Add(detailReader["ProductID"]); } conn.Close(); } private void Form1_Load(object sender, EventArgs e) { conn = new SqlConnection(); conn.ConnectionString = "SERVER=localhost;DATABASE=AdventureWorks;INTEGRATED SECURITY=true; MIN POOL SIZE=2; MAX POOL SIZE=10;MultipleActiveResultSets=true;"; } }
3.批量復制操作
a)Microsoft SQL Server 包含名為bcp的常用命令行應用程序,
用於快速將大文件批量復制到SQL Server 數據庫的表或視圖中。
b)使用SqlBulkCopy 類可以編寫提供類似功能的托管代碼解決方案。
c)還可以通過其他方式將數據加載到SQL Server 表中(例如INSERT 語句),
但是SqlBulkCopy 提供的性能要明顯優於這些方式。
代碼如下(此處只做演示):

public partial class Form1 : Form { public Form1() { //This call is required by the Windows Form Designer. InitializeComponent(); } private void bulkCopyForm_Load(System.Object sender, System.EventArgs e) { //Use a utility function to create the destination database for the sample CreateDestination(); } private void copyDataButton_Click(System.Object sender, System.EventArgs e) { // Retrieve data from the source server. SqlConnection sourceConn = new SqlConnection("SERVER=localhost;DATABASE=AdventureWorks;INTEGRATED SECURITY=true;"); SqlDataAdapter dA = new SqlDataAdapter("SELECT ProductID, Name, ListPrice FROM Production.Product", sourceConn); DataSet ds = new DataSet(); dA.Fill(ds, "Products"); // Connect to the destination server. SqlConnection destConn = new SqlConnection("SERVER=localhost;DATABASE=AWProductsData;Integrated Security=TRUE"); destConn.Open(); //count the existing rows SqlCommand verifyCmd = new SqlCommand("SELECT COUNT(*) FROM dbo.Products", destConn); int initialCount = System.Convert.ToInt32(verifyCmd.ExecuteScalar()); //Perform the copy operation using (SqlBulkCopy bcp = new SqlBulkCopy(destConn)) { bcp.DestinationTableName = "dbo.Products"; // Note that if column names matched, no mappings would be needed. bcp.ColumnMappings.Add("ProductID", "ProductCode"); bcp.ColumnMappings.Add("Name", "ProductName"); bcp.ColumnMappings.Add("ListPrice", "Price"); bcp.WriteToServer(ds.Tables["Products"]); } //Verify the data transfer int postCopyCount = System.Convert.ToInt32(verifyCmd.ExecuteScalar()); int copiedRows = postCopyCount - initialCount; MessageBox.Show(copiedRows.ToString() + " rows copied"); destConn.Close(); } #region "Utility code" private void CreateDestination() { try { using (SqlConnection conn = new SqlConnection("SERVER=localhost;DATABASE=master;INTEGRATED SECURITY=true")) { conn.Open(); SqlCommand SqlCmd = new SqlCommand("CREATE DATABASE AWProductsData", conn); SqlCmd.ExecuteNonQuery(); SqlCmd.CommandText = "CREATE TABLE AWProductsData.dbo.Products (ProductCode integer, ProductName nvarchar(40), Price money)"; SqlCmd.ExecuteNonQuery(); conn.Close(); } } catch (Exception Ex) { MessageBox.Show(Ex.Message); } } #endregion }
4)批處理更新
a)在上一個版本的ADO.NET 當中,SqlDataAdapter的Update方法
將會為DataSet當中的每一行調用一次更新操作。
b)在ADO.NET 2.0中,您可以設置UpdateBatchSize 屬性,在單步中執行多個更新。
這樣,可以提高數據更新的效率。
c)UpdateBatchSize 的默認值為1 使得默認的更新行為與以前版本的ADO.NET 一致。
代碼如下:

public partial class Form1 : Form { public Form1() { conn = new SqlConnection(ConfigurationManager.ConnectionStrings["AWConnectionString"].ConnectionString); dAdapt = new SqlDataAdapter("SELECT ProductID, Name, ListPrice FROM Production.Product", conn); InitializeComponent(); } SqlConnection conn; SqlDataAdapter dAdapt; DataSet dSet = new DataSet(); StringBuilder logString = new StringBuilder(""); private void batchUpdateForm_Load(System.Object sender, System.EventArgs e) { dAdapt.RowUpdating += OnRowUpdating; dAdapt.RowUpdated += OnRowUpdated; } private void getDataButton_Click(System.Object sender, System.EventArgs e) { dAdapt.Fill(dSet, "Product"); productGrid.DataSource = dSet.Tables["Product"]; } private void updateDataButton_Click(System.Object sender, System.EventArgs e) { SqlCommandBuilder cb = new SqlCommandBuilder(dAdapt); logString.Remove(0, logString.Length); // Enable batching by setting batch size != 1. dAdapt.UpdateBatchSize = int.Parse(batchSizeTextBox.Text); // Execute the update. dAdapt.Update(dSet.Tables["Product"]); MessageBox.Show(logString.ToString()); } //handler for the RowUpdating event public void OnRowUpdating(object sender, SqlRowUpdatingEventArgs e) { logString.AppendLine("Starting row update"); } // handler for RowUpdated event public void OnRowUpdated(object sender, SqlRowUpdatedEventArgs e) { logString.AppendLine("Completed row update"); } }
5)通知
a)SQL Server 2005 中的查詢通知可以在數據修改時
通知客戶端應用程序
b)ADO.NET 提供兩種方式來利用查詢通知功能:
– 使用SqlDependency類,並處理OnChanged事件
– 使用SqlNotifcationRequest 類,使用它可以用來訪問自定義通知隊列
代碼如下:

public partial class Form1 : Form { public Form1() { conn = new SqlConnection(ConfigurationManager.ConnectionStrings["AWConnectionString"].ConnectionString); cmd = new SqlCommand("SELECT ProductID, Name, ListPrice FROM Production.Product", conn); dep = new SqlDependency(cmd); InitializeComponent(); } SqlConnection conn; SqlCommand cmd; SqlDependency dep; delegate void PopulateList(); private void notificationForm_Load(System.Object sender, System.EventArgs e) { //Assign the event handler for the dependency's OnChanged event dep.OnChange += new System.Data.SqlClient.OnChangeEventHandler(OnDependencyChanged); SqlDependency.Start(conn.ConnectionString); //Retrieve the initial data ListProducts(); } public void OnDependencyChanged(object sender, SqlNotificationEventArgs e) { //Event handler for OnChanged event of Dependency DialogResult dR; dR = MessageBox.Show("The data has changed. Refresh?", e.Info.ToString(), MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (dR == System.Windows.Forms.DialogResult.Yes) { //Refresh the data this.Invoke(new PopulateList(ListProducts)); } } public void ListProducts() { productListBox.Items.Clear(); conn.Open(); SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { productListBox.Items.Add(reader["Name"].ToString() + ": " + reader["ListPrice"].ToString()); } conn.Close(); } }
6)快照隔離級別
a)SQL Server 2005 提供了快照隔離級別,用戶可以訪問行中上一個已提交的版本
b)ADO.NET SqlTransaction 類技術一個新的IsolationLevel Snapshot枚舉值
使得ADO.NET 客戶端應用程序可以利用快照隔離級別
c)先在數據庫上啟用
ALTER DATABASE AdventureWorks
SET ALLOW_SNAPSHOT_ISOLATION ON
代碼如下:

public partial class Form1 : Form { public Form1() { conn = new SqlConnection(ConfigurationManager.ConnectionStrings["AWConnectionString"].ConnectionString); InitializeComponent(); } SqlConnection conn; SqlCommand cmd = new SqlCommand(); SqlTransaction tran; private void snapshotForm_Load(System.Object sender, System.EventArgs e) { try { conn.Open(); //Start a transaction using snapshot isolation tran = conn.BeginTransaction(IsolationLevel.Snapshot); cmd.Connection = conn; cmd.Transaction = tran; RetrieveData(); } catch (Exception Ex) { MessageBox.Show(Ex.Message); } } private void updateButton_Click(System.Object sender, System.EventArgs e) { try { //update the data cmd.CommandText = "Update Production.Product SET ListPrice = ListPrice + 2 WHERE ProductID = 1"; cmd.ExecuteNonQuery(); RetrieveData(); } catch (Exception Ex) { MessageBox.Show(Ex.Message); } } private void commitButton_Click(System.Object sender, System.EventArgs e) { try { //commit the transaction tran.Commit(); conn.Close(); } catch (Exception Ex) { MessageBox.Show(Ex.Message); } } public void RetrieveData() { productListBox.Items.Clear(); cmd.CommandText = "SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID < 10"; SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { productListBox.Items.Add(reader["Name"].ToString() + ": " + reader["ListPrice"].ToString()); } reader.Close(); } }
7)數據庫鏡像
a)服務器角色
– 主服務器
存儲主數據庫的服務器
用戶連接到服務器
– 鏡像服務器
存儲鏡像數據庫的服務器
在主服務器出現故障后,用戶連接到該服務器
– 見證服務器
在主服務器與鏡像服務器之間它們的監視連通性
8)配置客戶端應用程序
a)使用.NET Framework 2.0進行開發
b)連接字符串: 連接字符串:
– 只需要添加“failover partner”參數
– 例如: connectionString="server=(local);database=AdventureWorks;Integrated Security=true;Failover Partner=(local)\MIRROR"
代碼如下(注意鏈接字符串):

static class Program { /// <summary> /// 應用程序的主入口點。 /// </summary> static void Main() { SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["AdventureWorks"].ConnectionString); while (true) { try { conn.Open(); SqlCommand comm = conn.CreateCommand(); comm.CommandType = CommandType.Text; comm.CommandText = "SELECT @@ServerName"; Console.WriteLine(comm.ExecuteScalar().ToString()); Thread.Sleep(2000); conn.Close(); } catch (Exception e) { Console.WriteLine(e.Message); } } } }