NET Framework 2.0中的數據訪問新特性


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

View Code
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";

代碼如下:

View Code
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 提供的性能要明顯優於這些方式。
代碼如下(此處只做演示):

View Code
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 一致。

代碼如下:

View Code
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 類,使用它可以用來訪問自定義通知隊列

代碼如下:

View Code
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

代碼如下:

View Code
    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"

代碼如下(注意鏈接字符串):

View Code
    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);
                }
            }
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM