<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>.NET(ADO.NET)</title><link>http://blog.blueshop.com.tw/topcat/category/718.aspx</link><description>ADO.NET物件開發技術分享</description><managingEditor>topcat</managingEditor><dc:language>zh-TW</dc:language><generator>.Text Version 0.95.2004.101</generator><item><dc:creator>topcat</dc:creator><title>物件Object的New,Dispose與Connection的Open,Close概念分享</title><link>http://blog.blueshop.com.tw/topcat/archive/2008/07/03/55733.aspx</link><pubDate>Thu, 03 Jul 2008 16:27:00 GMT</pubDate><guid>http://blog.blueshop.com.tw/topcat/archive/2008/07/03/55733.aspx</guid><wfw:comment>http://blog.blueshop.com.tw/topcat/comments/55733.aspx</wfw:comment><comments>http://blog.blueshop.com.tw/topcat/archive/2008/07/03/55733.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blog.blueshop.com.tw/topcat/comments/commentRss/55733.aspx</wfw:commentRss><trackback:ping>http://blog.blueshop.com.tw/topcat/services/trackbacks/55733.aspx</trackback:ping><description>&lt;p&gt;這篇文章源自於有位網友對於Using的疑問(&lt;a title="http://www.blueshop.com.tw/board/show.asp?subcde=BRD20080703145519KXS&amp;amp;fumcde=FUM20041006161839LRJ" href="http://www.blueshop.com.tw/board/show.asp?subcde=BRD20080703145519KXS&amp;amp;fumcde=FUM20041006161839LRJ"&gt;http://www.blueshop.com.tw/board/show.asp?subcde=BRD20080703145519KXS&amp;amp;fumcde=FUM20041006161839LRJ&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;小喵就小喵的認知來說明，不見得正確，如有錯誤請大家指正，感恩&lt;/p&gt;&lt;h1&gt;什麼是New&lt;/h1&gt;&lt;p&gt;我們經常可以看到有人使用一個物件的時候會寫&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:6c28b5f7-ec51-41e2-91e6-5b1e05bd26da" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre class="vb" name="code"&gt;
Dim oEmp as ObjEmployee
oEmp = New ObjEmployee
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;而且少了New就不能執行，那麼什麼是New呢 &lt;a href="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E5%97%AF_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="54" alt="嗯" width="54" border="0" src="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E5%97%AF_thumb.gif" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;New&lt;/font&gt;&lt;/strong&gt;是產生執行個體，不過相信很多人又要問，什麼是【&lt;strong&gt;&lt;font color="#0000ff"&gt;產生執行個體&lt;/font&gt;&lt;/strong&gt;】 (能不能講明白一點啊!!&lt;a href="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E7%81%AB%E5%A4%A7_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="54" alt="火大" width="54" border="0" src="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E7%81%AB%E5%A4%A7_thumb.gif" /&gt;&lt;/a&gt; ) &lt;br /&gt;這要提到電腦的程式運作過程。程式在電腦上跑，會把程式的區段，在記憶體裡面挖一塊空間，然後把程式碼載入那塊空間 &lt;br /&gt;接著程式在運作的時候，就是記憶體與CPU之間溝通、運算、記錄等動作，而把【&lt;strong&gt;&lt;font color="#0000ff"&gt;挖塊記憶體，把程式載到那塊空間&lt;/font&gt;&lt;/strong&gt;】這個過程就是【&lt;strong&gt;&lt;font color="#0000ff"&gt;產生執行個體&lt;/font&gt;&lt;/strong&gt;】。 &lt;br /&gt;因此沒有New的話會怎樣，程式區塊根本沒有載入到記憶體中，因此也無法運作執行&lt;/p&gt;&lt;p&gt;講的擬人化一點&lt;/p&gt;&lt;p&gt;Dim oEmp as ObjEmployee&amp;nbsp; '宣告oEmp是ObjEmployee這種物件類別(此時有魂無體)&lt;a href="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E6%9C%89%E9%AC%BC_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="54" alt="有鬼" width="54" border="0" src="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E6%9C%89%E9%AC%BC_thumb.gif" /&gt;&lt;/a&gt; &lt;br /&gt;oEmp = New ObjEmployee&amp;nbsp;&amp;nbsp; '產生執行個體(此時投胎轉世，靈魂變成實體，可以開始工作)&lt;a href="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E6%9C%89%E4%B8%80%E5%A5%97_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="54" alt="有一套" width="54" border="0" src="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E6%9C%89%E4%B8%80%E5%A5%97_thumb.gif" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;h1&gt;什麼是Dispose&lt;/h1&gt;&lt;p&gt;&lt;br /&gt;當一個物件已經使用完後，未來不會再使用，此時這個物件已經完成他這一生(New完之後到現在)的任務。因此他可以塵歸塵、土歸土...一切還諸天地...此時就進行Dispose &lt;a href="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E6%9C%89%E9%AC%BC_4.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="54" alt="有鬼" width="54" border="0" src="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E6%9C%89%E9%AC%BC_thumb_1.gif" /&gt;&lt;/a&gt; &lt;br /&gt;然而實際上，在記憶體中，&lt;strong&gt;當物件Dispose的時候，並沒有把該段記憶體清空，只是標註，這段空間不再使用&lt;/strong&gt;，直到GC啟動把他清空才算真正的清空。 &lt;br /&gt;因此如果用完後，不進行Dispose...那麼就會等到該位置很久沒動作了(就像有個人躺在地上，已經超過一定時間(一個月??)沒動作，也沒呼吸)，才會被其他的程式拿來用。&lt;/p&gt;&lt;p&gt;以上說明的是New(生)與Dispose(死)的關係&lt;/p&gt;&lt;hr /&gt;&lt;h1&gt;什麼是Open&lt;/h1&gt;&lt;p&gt;&lt;br /&gt;當你有了實體後，代表可以開始運作 &lt;br /&gt;但不是真的已經運作了 &lt;br /&gt;以Connecion來說&lt;/p&gt;&lt;div class="wlWriterSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:5194bae2-d5af-48fe-a9f8-dcd0e1d84fe6" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre class="vb" name="code"&gt;
Using Conn As New Connetion(ConnStr)
    'Conn.Open
    Dim Dr as SqlDataReader
    Using Cmmd as New SqlCommand(&amp;quot;Select...&amp;quot;,Conn)
        Dr = Cmmd.ExecuteReader
    End Using
End Using
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面這段程式會出錯，他告訴你...Connection沒有Open，也就例如您&lt;strong&gt;&lt;font color="#0000ff"&gt;建立了一個橋&lt;/font&gt;&lt;/strong&gt;，但是這座橋卻&lt;strong&gt;&lt;font color="#0000ff"&gt;沒有通車&lt;/font&gt;&lt;/strong&gt;，因此也沒辦法用。因此使用DataReader或者Cmmd.ExecuteNoneQuery的時候，都需要告訴他已經通車了...他才會正常運作。&lt;/p&gt;&lt;p&gt;而如果使用&lt;strong&gt;&lt;font color="#0000ff"&gt;DataAdapter&lt;/font&gt;&lt;/strong&gt;的話這個傢伙比較厲害...&lt;a href="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E8%AE%9A_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="54" alt="讚" width="54" border="0" src="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E8%AE%9A_thumb.gif" /&gt;&lt;/a&gt; 他會看有沒有通車，有通車他就用；沒通車的話，他會&lt;strong&gt;自己把這通道打開&lt;/strong&gt;，然後去使用。&lt;/p&gt;&lt;h1&gt;最後說什麼是Close...&lt;/h1&gt;&lt;p&gt;Close是關閉通道，通道關了是可以再開的唷。 &lt;br /&gt;然後跟上面的Dispose再比對一下： &lt;br /&gt;Close只是把通道關閉 &lt;br /&gt;Dispose卻是通知作業系統...我已經完成任務，這段記憶體你可以拿去再用...然後壽終正寢 &lt;br /&gt;知道不一樣在哪了嗎??&lt;a href="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E5%B9%B8%E7%A6%8F_2.gif"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="54" alt="幸福" width="54" border="0" src="http://files.dotblogs.com.tw/topcat/0807/ConnectionNewDisposeOpenClose_E240/%E5%B9%B8%E7%A6%8F_thumb.gif" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src ="http://blog.blueshop.com.tw/topcat/aggbug/55733.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>topcat</dc:creator><title>ObjectDataSouce簡介Part 2：範例程式(含畫面設定錄影教學)</title><link>http://blog.blueshop.com.tw/topcat/archive/2008/07/01/55660.aspx</link><pubDate>Tue, 01 Jul 2008 08:43:00 GMT</pubDate><guid>http://blog.blueshop.com.tw/topcat/archive/2008/07/01/55660.aspx</guid><wfw:comment>http://blog.blueshop.com.tw/topcat/comments/55660.aspx</wfw:comment><comments>http://blog.blueshop.com.tw/topcat/archive/2008/07/01/55660.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.blueshop.com.tw/topcat/comments/commentRss/55660.aspx</wfw:commentRss><trackback:ping>http://blog.blueshop.com.tw/topcat/services/trackbacks/55660.aspx</trackback:ping><description>&lt;p&gt;承繼上篇【&lt;a href="http://www.dotblogs.com.tw/topcat/archive/2008/06/27/4395.aspx"&gt;ObjectDataSouce簡介Part1：兼具ADO.NET的自由與DataSouce的方便&lt;/a&gt;】，我們這篇就來拿個實際範例，告訴各位如何撰寫相關的程式。&lt;/p&gt;

&lt;p&gt;首先介紹上次提到的這樣的方式&lt;/p&gt;

&lt;p&gt;&lt;img alt="" src="http://files.dotblogs.com.tw/topcat/0806/ObjectDataSoucePart1ADO.NETDataSouce_76BC/ods02_2.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;先示範如何撰寫類別的部分。&lt;/p&gt;

&lt;p&gt;首先，小喵建立一個物件用來讀取Connection String，未來無論Connection String用什麼方式來存放(存放的方式很多，可以直接放在物件中，也可放在Web.Config，小喵自己是存在沒有Web分享的硬碟裡)，都可以透過這個物件來取得Connection String。&lt;/p&gt;

&lt;p&gt;在專案中新增一個類別，取名為【objConnS.vb】，內容如下：&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Imports&lt;/span&gt; Microsoft.VisualBasic

&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Class&lt;/span&gt; objConnS
    &lt;span class="kwrd"&gt;Private&lt;/span&gt; m_ConnStr &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="str"&gt;&amp;quot;Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\NORTHWND.MDF;Integrated Security=True;User Instance=True&amp;quot;&lt;/span&gt;

    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; ConnStr() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;
        &lt;span class="kwrd"&gt;Get&lt;/span&gt;
            &lt;span class="kwrd"&gt;Return&lt;/span&gt; m_ConnStr
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt;
&lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Class&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;接著開始撰寫資料存取的類別(我們以北風資料庫中的Customers當作示範，示範時只取其中四個欄位當範例)，小喵取名為【daoCustomer.vb】，裡面寫了5個副程式，其中兩個Select用的用Function，剩下3個新增修改刪除不需要傳回值，就用Sub即可(當然如果想傳回值用Function也可)。程式內容如下：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;GetAllCusts()：用DataTable傳回所有的Customers&lt;/li&gt;

  &lt;li&gt;GetCustByID(ByVal CustomerID As String)：用參數傳入條件CustomerID，傳回符合條件的一筆，這可以用來當作是單筆維護的處理&lt;/li&gt;

  &lt;li&gt;UpdateCustomers,InsertCustomers,DeleteCustomers這三個則是透過參數傳遞要新增修改刪除的相關資料，然後透過ADO.NET維護資料。&lt;/li&gt;
&lt;/ol&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Imports&lt;/span&gt; System.Data
&lt;span class="kwrd"&gt;Imports&lt;/span&gt; System.Data.SqlClient
&lt;span class="kwrd"&gt;Imports&lt;/span&gt; Microsoft.VisualBasic

&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Class&lt;/span&gt; daoCustomer

    &lt;span class="kwrd"&gt;Private&lt;/span&gt; oConnS &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; objConnS
    &lt;span class="kwrd"&gt;Private&lt;/span&gt; ConnStr &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = oConnS.ConnStr


    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; GetAllCusts() &lt;span class="kwrd"&gt;As&lt;/span&gt; DataTable
        &lt;span class="kwrd"&gt;Try&lt;/span&gt;
            Using Conn &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; SqlConnection(ConnStr)
                Conn.Open()
                &lt;span class="kwrd"&gt;Dim&lt;/span&gt; SqlTxt &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot; SELECT  CustomerID,  CompanyName,  ContactName,  City  &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot; FROM Customers &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot;  &amp;quot;&lt;/span&gt;

                &lt;span class="kwrd"&gt;Dim&lt;/span&gt; Dt &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; DataTable
                Using Cmmd &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; SqlCommand(SqlTxt, Conn)
                    Dt.Load(Cmmd.ExecuteReader)
                &lt;span class="kwrd"&gt;End&lt;/span&gt; Using
                &lt;span class="kwrd"&gt;Return&lt;/span&gt; Dt

            &lt;span class="kwrd"&gt;End&lt;/span&gt; Using
        &lt;span class="kwrd"&gt;Catch&lt;/span&gt; ex &lt;span class="kwrd"&gt;As&lt;/span&gt; Exception
            &lt;span class="kwrd"&gt;Throw&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; Exception(ex.Message)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Try&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt;

    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; GetCustByID(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; CustomerID &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;) &lt;span class="kwrd"&gt;As&lt;/span&gt; DataTable
        &lt;span class="kwrd"&gt;Try&lt;/span&gt;
            &lt;span class="kwrd"&gt;If&lt;/span&gt; CustomerID &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                CustomerID = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            Using Conn &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; SqlConnection(ConnStr)
                Conn.Open()
                &lt;span class="kwrd"&gt;Dim&lt;/span&gt; SqlTxt &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot; SELECT CustomerID,  CompanyName,  ContactName,  City &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot; FROM Customers &amp;quot;&lt;/span&gt;
                &lt;span class="kwrd"&gt;If&lt;/span&gt; CustomerID &amp;lt;&amp;gt; &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                    SqlTxt += &lt;span class="str"&gt;&amp;quot; WHERE CustomerID = @CustomerID &amp;quot;&lt;/span&gt;
                &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot;  &amp;quot;&lt;/span&gt;
                &lt;span class="kwrd"&gt;Dim&lt;/span&gt; Dt &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; DataTable
                Using Cmmd &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; SqlCommand(SqlTxt, Conn)
                    &lt;span class="kwrd"&gt;If&lt;/span&gt; CustomerID &amp;lt;&amp;gt; &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                        Cmmd.Parameters.AddWithValue(&lt;span class="str"&gt;&amp;quot;@CustomerID&amp;quot;&lt;/span&gt;, CustomerID)
                    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
                    Dt.Load(Cmmd.ExecuteReader)
                &lt;span class="kwrd"&gt;End&lt;/span&gt; Using
                &lt;span class="kwrd"&gt;Return&lt;/span&gt; Dt

            &lt;span class="kwrd"&gt;End&lt;/span&gt; Using
        &lt;span class="kwrd"&gt;Catch&lt;/span&gt; ex &lt;span class="kwrd"&gt;As&lt;/span&gt; Exception
            &lt;span class="kwrd"&gt;Throw&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; Exception(ex.Message)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Try&lt;/span&gt;

    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt;

    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; UpdateCustomers(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; CustomerID &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; CompanyName &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; ContactName &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; City &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;)
        &lt;span class="kwrd"&gt;Try&lt;/span&gt;
            &lt;span class="kwrd"&gt;If&lt;/span&gt; CustomerID &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                CustomerID = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            &lt;span class="kwrd"&gt;If&lt;/span&gt; CompanyName &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                CompanyName = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            &lt;span class="kwrd"&gt;If&lt;/span&gt; ContactName &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                ContactName = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            &lt;span class="kwrd"&gt;If&lt;/span&gt; City &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                City = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            Using Conn &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; SqlConnection(ConnStr)
                Conn.Open()
                &lt;span class="kwrd"&gt;Dim&lt;/span&gt; SqlTxt &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot; UPDATE Customers &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot; SET CompanyName = @CompanyName &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot;     ,ContactName = @ContactName &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot;     ,City = @City &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot; WHERE CustomerID = @CustomerID &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot;  &amp;quot;&lt;/span&gt;
                Using Cmmd &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; SqlCommand(SqlTxt, Conn)
                    Cmmd.Parameters.AddWithValue(&lt;span class="str"&gt;&amp;quot;@CompanyName&amp;quot;&lt;/span&gt;, CompanyName)
                    Cmmd.Parameters.AddWithValue(&lt;span class="str"&gt;&amp;quot;@ContactName&amp;quot;&lt;/span&gt;, ContactName)
                    Cmmd.Parameters.AddWithValue(&lt;span class="str"&gt;&amp;quot;@City&amp;quot;&lt;/span&gt;, City)
                    Cmmd.Parameters.AddWithValue(&lt;span class="str"&gt;&amp;quot;@CustomerID&amp;quot;&lt;/span&gt;, CustomerID)
                    Cmmd.ExecuteNonQuery()
                &lt;span class="kwrd"&gt;End&lt;/span&gt; Using
            &lt;span class="kwrd"&gt;End&lt;/span&gt; Using
        &lt;span class="kwrd"&gt;Catch&lt;/span&gt; ex &lt;span class="kwrd"&gt;As&lt;/span&gt; Exception
            &lt;span class="kwrd"&gt;Throw&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; Exception(ex.Message)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Try&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; InsertCustomers(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; CustomerID &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; CompanyName &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; ContactName &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; City &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;)
        &lt;span class="kwrd"&gt;Try&lt;/span&gt;
            &lt;span class="kwrd"&gt;If&lt;/span&gt; CustomerID &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                CustomerID = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            &lt;span class="kwrd"&gt;If&lt;/span&gt; CompanyName &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                CompanyName = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            &lt;span class="kwrd"&gt;If&lt;/span&gt; ContactName &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                ContactName = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
            &lt;span class="kwrd"&gt;If&lt;/span&gt; City &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
                City = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
            &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;

            Using Conn &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; SqlConnection(ConnStr)
                Conn.Open()
                &lt;span class="kwrd"&gt;Dim&lt;/span&gt; SqlTxt &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot; INSERT INTO Customers &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot;     (CustomerID, CompanyName, ContactName, City) &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot; VALUES (@CustomerID, @CompanyName, @ContactName, @City) &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot;  &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot;  &amp;quot;&lt;/span&gt;
                Using Cmmd &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; SqlCommand(SqlTxt, Conn)
                    Cmmd.Parameters.AddWithValue(&lt;span class="str"&gt;&amp;quot;@CompanyName&amp;quot;&lt;/span&gt;, CompanyName)
                    Cmmd.Parameters.AddWithValue(&lt;span class="str"&gt;&amp;quot;@ContactName&amp;quot;&lt;/span&gt;, ContactName)
                    Cmmd.Parameters.AddWithValue(&lt;span class="str"&gt;&amp;quot;@City&amp;quot;&lt;/span&gt;, City)
                    Cmmd.Parameters.AddWithValue(&lt;span class="str"&gt;&amp;quot;@CustomerID&amp;quot;&lt;/span&gt;, CustomerID)
                    Cmmd.ExecuteNonQuery()

                &lt;span class="kwrd"&gt;End&lt;/span&gt; Using
            &lt;span class="kwrd"&gt;End&lt;/span&gt; Using
        &lt;span class="kwrd"&gt;Catch&lt;/span&gt; ex &lt;span class="kwrd"&gt;As&lt;/span&gt; Exception
            &lt;span class="kwrd"&gt;Throw&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; Exception(ex.Message)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Try&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;

    &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; DeleteCustomers(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; CustomerID &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;)
        &lt;span class="kwrd"&gt;Try&lt;/span&gt;
            Using Conn &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; SqlConnection(ConnStr)
                Conn.Open()
                &lt;span class="kwrd"&gt;Dim&lt;/span&gt; SqlTxt &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot; DELETE Customers &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot; WHERE CustomerID = @CustomerID &amp;quot;&lt;/span&gt;
                SqlTxt += &lt;span class="str"&gt;&amp;quot;  &amp;quot;&lt;/span&gt;
                Using Cmmd &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; SqlCommand(SqlTxt, Conn)
                    Cmmd.Parameters.AddWithValue(&lt;span class="str"&gt;&amp;quot;@CustomerID&amp;quot;&lt;/span&gt;, CustomerID)
                    Cmmd.ExecuteNonQuery()

                &lt;span class="kwrd"&gt;End&lt;/span&gt; Using
            &lt;span class="kwrd"&gt;End&lt;/span&gt; Using
        &lt;span class="kwrd"&gt;Catch&lt;/span&gt; ex &lt;span class="kwrd"&gt;As&lt;/span&gt; Exception
            &lt;span class="kwrd"&gt;Throw&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; Exception(ex.Message)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Try&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;
&lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Class&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;其中為了避免程式一開始，傳遞的參數是Nothing造成程式的錯誤，因此在程式中判斷如果傳入的參數是Nothing，就給預設值。&lt;/p&gt;

&lt;p&gt;寫好了物件後，接著就來看怎麼編輯畫面，怎麼設定ObjectDataSouce，怎麼讓物件控制相透過我們寫好的程式動起來。這部分請參考以下的錄影說明。(包含畫面設定、錯誤處理等)&lt;/p&gt;

&lt;p&gt;錄影： &lt;a title="http://vip2.blueshop.com.tw/topcat/DEMO/tObjectDataSouce/tObjectDataSouce.html" href="http://vip2.blueshop.com.tw/topcat/DEMO/tObjectDataSouce/tObjectDataSouce.html" target="_blank"&gt;http://vip2.blueshop.com.tw/topcat/DEMO/tObjectDataSouce/tObjectDataSouce.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;範例程式下載：&lt;a title="http://vip2.blueshop.com.tw/topcat/DEMO/tObjectDataSouce/tObjectDataSouce.html" href="http://vip2.blueshop.com.tw/topcat/DEMO/tObjectDataSouce/tObjectDataSouce.zip" target="_blank"&gt;http://vip2.blueshop.com.tw/topcat/DEMO/tObjectDataSouce/tObjectDataSouce.zip&lt;/a&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;而如果是結合商用物件的方式&lt;/p&gt;

&lt;p&gt;&lt;img alt="" src="http://files.dotblogs.com.tw/topcat/0806/ObjectDataSoucePart1ADO.NETDataSouce_76BC/ods03_thumb.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;請參考小喵的另外一篇文章裡面有範例&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;a href="http://www.dotblogs.com.tw/topcat/archive/2008/06/20/4346.aspx" target="_blank"&gt;ObjectDataSouce結合物件設計方式&lt;/a&gt;&lt;/p&gt;
&lt;img src ="http://blog.blueshop.com.tw/topcat/aggbug/55660.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>topcat</dc:creator><title>ObjectDataSouce簡介Part1：兼具ADO.NET的自由與DataSouce的方便</title><link>http://blog.blueshop.com.tw/topcat/archive/2008/07/01/55659.aspx</link><pubDate>Tue, 01 Jul 2008 08:43:00 GMT</pubDate><guid>http://blog.blueshop.com.tw/topcat/archive/2008/07/01/55659.aspx</guid><wfw:comment>http://blog.blueshop.com.tw/topcat/comments/55659.aspx</wfw:comment><comments>http://blog.blueshop.com.tw/topcat/archive/2008/07/01/55659.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.blueshop.com.tw/topcat/comments/commentRss/55659.aspx</wfw:commentRss><trackback:ping>http://blog.blueshop.com.tw/topcat/services/trackbacks/55659.aspx</trackback:ping><description>&lt;p&gt;一般市面上介紹的書籍，大部分都會從SqlDataSouce與GridView,DetailView等DataControl來介紹，當然這些東西很方便，可以在最少的程式碼的情況下，做出新增修改刪除查詢。但是，事實上在專案開發下並非如想像中這麼美好，您不會永遠都是處理單一資料表的新增修改刪除查詢。當遇到要處理兩個資料表以上的時候，又該如何呢??&lt;/p&gt;&lt;p&gt;在ASP.NET 2.0裡面多了一個ObjectDataSouce，這個東西可以讓我們在處理資料的時候，可以透過自己寫的程式，或者已經開發好的物件來撰寫。&lt;/p&gt;&lt;p&gt;我們從以下的示意圖來看：&lt;/p&gt;&lt;p&gt;1.SqlDataSouce：&lt;/p&gt;&lt;p&gt;&lt;a href="http://files.dotblogs.com.tw/topcat/0806/ObjectDataSoucePart1ADO.NETDataSouce_76BC/ods01_2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="131" alt="ods01" width="612" border="0" src="http://files.dotblogs.com.tw/topcat/0806/ObjectDataSoucePart1ADO.NETDataSouce_76BC/ods01_thumb.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;SqlDataSouce透過Select,Insert,Update,Delete四種Command設定來存取資料&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;2.使用ObjectDataSouce&lt;/p&gt;&lt;p&gt;&lt;a href="http://files.dotblogs.com.tw/topcat/0806/ObjectDataSoucePart1ADO.NETDataSouce_76BC/ods02_2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="130" alt="ods02" width="609" border="0" src="http://files.dotblogs.com.tw/topcat/0806/ObjectDataSoucePart1ADO.NETDataSouce_76BC/ods02_thumb.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;ObjectDataSouce則是透過指定的類別、以及類別中所撰寫的Method(Function/Sub)來處理，其中Select必須傳回結果，傳回的結果可以用這幾種方式【DataReader、DataSet、DataTable、DavaView、Collection Objects(物件集合)】，也就是一般在寫Me.GridView1.DataSouce=XXXX這裡可以傳入的型態。而其他Insert,Update,Delete則是需要配合傳遞要維護的資料，並在裡面透過ADO.NET存取資料。&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;3.使用ObjectDataSouce配合Business Object(*.dll/Class)&lt;/p&gt;&lt;p&gt;&lt;a href="http://files.dotblogs.com.tw/topcat/0806/ObjectDataSoucePart1ADO.NETDataSouce_76BC/ods03_2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="84" alt="ods03" width="607" border="0" src="http://files.dotblogs.com.tw/topcat/0806/ObjectDataSoucePart1ADO.NETDataSouce_76BC/ods03_thumb.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;可以再把資料的存取、以及一些商業邏輯抽出來，寫成一些商用物件，然後在寫個類別來運用這些商用物件，與ObjectDataSouce結合。&lt;/p&gt;&lt;p&gt;從這邊我們可以了解，使用ObjectDataSouce，可以自己撰寫程式來做資料的存取。能夠依照自己的需求來撰寫程式，讓系統能夠更靈活的應用。又可以透過DataSouce的機制，與資料控制項(例如GridView,DetailView,FormView等)結合。讓界面的部分能夠將程式減少，應用更為便利。可說是【兼具ADO.NET的自由與DataSouce的方便】。&lt;/p&gt;&lt;p&gt;至於2.3的方式如何撰寫，我們將在另外的文章中介紹。&lt;/p&gt;&lt;p&gt;^_^&lt;/p&gt;&lt;img src ="http://blog.blueshop.com.tw/topcat/aggbug/55659.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>topcat</dc:creator><title>確保交易的新利器(TransactionScope)初體驗-Part 2(物件維護的交易確保)</title><link>http://blog.blueshop.com.tw/topcat/archive/2008/05/16/55050.aspx</link><pubDate>Fri, 16 May 2008 11:26:00 GMT</pubDate><guid>http://blog.blueshop.com.tw/topcat/archive/2008/05/16/55050.aspx</guid><wfw:comment>http://blog.blueshop.com.tw/topcat/comments/55050.aspx</wfw:comment><comments>http://blog.blueshop.com.tw/topcat/archive/2008/05/16/55050.aspx#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://blog.blueshop.com.tw/topcat/comments/commentRss/55050.aspx</wfw:commentRss><trackback:ping>http://blog.blueshop.com.tw/topcat/services/trackbacks/55050.aspx</trackback:ping><description>&lt;P&gt;承繼上一篇【&lt;A href="http://www.dotblogs.com.tw/topcat/archive/2008/05/15/3997.aspx"&gt;&lt;FONT color=#002c99&gt;確保交易的新利器(TransactionScope)初體驗-Part 1(注意Scope.Complete的位置)&lt;/FONT&gt;&lt;/A&gt;】接著小喵有興趣的事，現在很多人開始使用OOP設計系統，那麼在一個商業邏輯中，透過兩個以上的物件來分別維護數個資料，在這樣的過程中，又如何確保交易的完整性呢。&lt;/P&gt;
&lt;P&gt;於是小喵再次撰寫個物件來做個測試，這次針對北風資料庫的Employees這個資料表的內容來設計一個Employee物件，物件中有個UpdateEmployeeData的方法(Function)來維護Employee的資料&lt;/P&gt;
&lt;P&gt;透過分別建立兩個Employee物件執行個體，然後分別呼叫UpdateEmployeeData，跟上一個範例一樣：&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;建立Emp1,Emp9兩個物件執行個體，他們的EmployeeID分別為1,9 
&lt;LI&gt;將Emp1的LastName最後一個字加上【X】字元，這部分是應該可以過得 
&lt;LI&gt;小喵試著要把Emp9的FirstName設定為【ABC123456789】,從資料表Layout看出，FirstName欄位大小是10個字元，因此這個應該會出現錯誤&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;接著來看看程式碼的部分&lt;/P&gt;
&lt;P&gt;首先是objEmployee這個物件類別的內容如下：&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=wlWriterSmartContent id=scid:812469c5-0cb0-4c63-8c15-c81123a09de7:76abc71a-11b9-4b7a-8c0d-2ca369c62bfe style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;TEXTAREA class=vb name=code rows=6 cols=50&gt;Imports Microsoft.VisualBasic
Imports System.Data
Imports System.Data.SqlClient

Public Class objEmployee
    Private m_EmployeeID As Integer
    Private m_LastName As String
    Private m_FirstName As String
    Private m_Title As String
    Private m_TitleOfCourtesy As String
    Private m_BirthDate As DateTime
    Private m_HireDate As DateTime
    Private m_Address As String

    Public Property EmployeeID() As Integer
        Get
            Return m_EmployeeID
        End Get
        Set(ByVal value As Integer)
            m_EmployeeID = value
        End Set
    End Property

    Public Property LastName() As String
        Get
            Return m_LastName
        End Get
        Set(ByVal value As String)
            m_LastName = value
        End Set
    End Property

    Public Property FirstName() As String
        Get
            Return m_FirstName
        End Get
        Set(ByVal value As String)
            m_FirstName = value
        End Set
    End Property

    Public Property Title() As String
        Get
            Return m_Title
        End Get
        Set(ByVal value As String)
            m_Title = value
        End Set
    End Property

    Public Property TitleOfCourtesy() As String
        Get
            Return m_TitleOfCourtesy
        End Get
        Set(ByVal value As String)
            m_TitleOfCourtesy = value
        End Set
    End Property

    Public Property BithDay() As DateTime
        Get
            Return m_BirthDate
        End Get
        Set(ByVal value As DateTime)
            m_BirthDate = value
        End Set
    End Property

    Public Property HirDate() As DateTime
        Get
            Return m_HireDate
        End Get
        Set(ByVal value As DateTime)
            m_HireDate = value
        End Set
    End Property

    Public Property Address() As String
        Get
            Return m_Address
        End Get
        Set(ByVal value As String)
            m_Address = value
        End Set
    End Property

    Sub New()

    End Sub

    Sub New(ByVal myEmployeeID As Integer)
        m_EmployeeID = myEmployeeID
        GetEmployeeData()
    End Sub

    Public Sub GetEmployeeData()
        Dim oConnStr As New objConnStr
        Dim ConnStr As String = oConnStr.ConnectionString

        Using Conn As New SqlConnection(ConnStr)
            Conn.Open()
            Try
                Dim SqlTxt As String = ""
                SqlTxt += " SELECT * "
                SqlTxt += " FROM Employees "
                SqlTxt += " WHERE EmployeeID = @EmployeeID "
                SqlTxt += "  "
                Dim Cmmd As New SqlCommand(SqlTxt, Conn)
                Cmmd.Parameters.AddWithValue("@EmployeeID", m_EmployeeID)

                Dim Dr As SqlDataReader = Cmmd.ExecuteReader
                If Not Dr.HasRows Then
                    Throw New Exception("無此員工代號資料!!")
                End If

                Dr.Read()

                m_LastName = Dr.Item("LastName")
                m_FirstName = Dr.Item("FirstName")
                m_Title = Dr.Item("Title")
                m_TitleOfCourtesy = Dr.Item("TitleOfCourtesy")
                m_BirthDate = Dr.Item("BirthDate")
                m_HireDate = Dr.Item("HireDate")
                m_Address = Dr.Item("Address")

                Dr.Close()

            Catch ex As Exception
                Throw New Exception(ex.Message)

            End Try
        End Using
    End Sub

    Public Sub UpdateEmployee()
        Dim oConnStr As New objConnStr
        Dim ConnStr As String = oConnStr.ConnectionString

        Using Conn As New SqlConnection(ConnStr)
            Conn.Open()
            Try
                Dim SqlTxt As String = ""
                SqlTxt += " UPDATE Employees "
                SqlTxt += " SET "
                SqlTxt += "     LastName=@LastName "
                SqlTxt += "     ,FirstName=@FirstName "
                SqlTxt += "     ,Title=@Title "
                SqlTxt += "     ,TitleOfCourtesy=@TitleOfCourtesy "
                SqlTxt += "     ,BirthDate=@BirthDate "
                SqlTxt += "     ,HireDate=@HireDate "
                SqlTxt += "     ,Address=@Address "
                SqlTxt += " WHERE EmployeeID = @EmployeeID "
                SqlTxt += "  "
                Dim Cmmd As New SqlCommand(SqlTxt, Conn)
                Cmmd.Parameters.AddWithValue("@EmployeeID", m_EmployeeID)
                Cmmd.Parameters.AddWithValue("@LastName", m_LastName)
                Cmmd.Parameters.AddWithValue("@FirstName", m_FirstName)
                Cmmd.Parameters.AddWithValue("@Title", m_Title)
                Cmmd.Parameters.AddWithValue("@TitleOfCourtesy", m_TitleOfCourtesy)
                Cmmd.Parameters.AddWithValue("@BirthDate", m_BirthDate)
                Cmmd.Parameters.AddWithValue("@HireDate", m_HireDate)
                Cmmd.Parameters.AddWithValue("@Address", m_Address)

                Cmmd.ExecuteNonQuery()

            Catch ex As Exception
                Throw New Exception(ex.Message)
            End Try
        End Using
    End Sub
End Class&lt;/TEXTAREA&gt;&lt;/DIV&gt;&lt;/P&gt;
&lt;DIV class=wlWriterSmartContent style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;
&lt;P&gt;接著在畫面上安排第二顆按鈕，該按鈕按下後，進行以下的程式碼&lt;/P&gt;
&lt;P&gt;&lt;TEXTAREA class=vb name=code rows=6 cols=50&gt;        Dim Emp1 As New objEmployee()
        Emp1.EmployeeID = 1
        Emp1.GetEmployeeData()

        Dim Emp9 As New objEmployee(9)

        Using Scope As New TransactionScope
            Try
                Emp1.LastName = Emp1.LastName &amp;amp; "X"
                Emp1.UpdateEmployee()

                Emp9.FirstName = "ABC1234567890"
                Emp9.UpdateEmployee()

                Scope.Complete()
            Catch ex As Exception
                Response.Write(ex.Message)

            End Try
        End Using
        Me.GridView1.DataBind()&lt;/TEXTAREA&gt;&lt;/P&gt;
&lt;P&gt;從程式碼中可以看到，只要把要呼叫維護的部分，使用TransactionScrope包起來，這樣維護的過程就能夠包成一個Transaction，用來確保內交易內容的完整性。其中第一個部分沒問題，第二個部分會有Exception。所以直到End Using都沒有呼叫Scope.Complete()，因此就把異動的內容Rollback。使用起來真是簡單。&lt;/P&gt;
&lt;P&gt;恭喜老爺、賀喜夫人。以往小喵都是用COM+的特別寫法才能夠做到的事情。使用TransactionScope竟然輕鬆的就能夠辦到。這讓使用物件導向設計的人有了很好的解套方式。並更能夠讓物件的行為設計時更能夠獨立處理。例如訂單產生就會動用到【訂單物件】維護OrderHead,OrderDetail，同時透過【倉庫物件】維護機種的【可販數量】這樣的維護過程應該要包在一個Transaction裡面才是。&lt;/P&gt;
&lt;P&gt;最後，小喵運作過程中發生了【伺服器...上的MSDTC無法使用...】的訊息，代表主機上的MSDTC的服務沒有開啟，請到【服務】裡面找到【Distributed Transaction Coordinator】將之啟動，即可啟動MSDTC，更細部的設定在【元件服務】裡。&lt;/P&gt;&lt;/DIV&gt;&lt;img src ="http://blog.blueshop.com.tw/topcat/aggbug/55050.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>topcat</dc:creator><title>確保交易的新利器(TransactionScope)初體驗-Part 1(注意Scope.Complete的位置)</title><link>http://blog.blueshop.com.tw/topcat/archive/2008/05/16/55049.aspx</link><pubDate>Fri, 16 May 2008 10:51:00 GMT</pubDate><guid>http://blog.blueshop.com.tw/topcat/archive/2008/05/16/55049.aspx</guid><wfw:comment>http://blog.blueshop.com.tw/topcat/comments/55049.aspx</wfw:comment><comments>http://blog.blueshop.com.tw/topcat/archive/2008/05/16/55049.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.blueshop.com.tw/topcat/comments/commentRss/55049.aspx</wfw:commentRss><trackback:ping>http://blog.blueshop.com.tw/topcat/services/trackbacks/55049.aspx</trackback:ping><description>&lt;P&gt;從.NET Framework 2.0以後，有個新的東西稱之為TransactionScope，他可以讓我們在處理交易的時候，可以確保交易的完整性，並且使用十分的簡便，小喵在此測試一下他的撰寫方式與結果，在測試過程中，驚人的發現了MSDN範例的一個錯誤內容。&lt;/P&gt;
&lt;P&gt;小喵以北風資料庫當作小喵測試的資料。就選用Employee這個資料表來測試看看，我們先看一下資料表的Layout以及他本來資料的狀況&lt;/P&gt;
&lt;P&gt;資料表Layout&lt;/P&gt;
&lt;P&gt;&lt;A href="http://files.dotblogs.com.tw/topcat/0805/TransactionScopePart1Scope.Complete_9398/ts001_2.jpg"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=336 alt=ts001 src="http://files.dotblogs.com.tw/topcat/0805/TransactionScopePart1Scope.Complete_9398/ts001_thumb.jpg" width=381 border=0&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;原本資料狀況&lt;/P&gt;
&lt;P&gt;&lt;A href="http://files.dotblogs.com.tw/topcat/0805/TransactionScopePart1Scope.Complete_9398/ts002_2.jpg"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=227 alt=ts002 src="http://files.dotblogs.com.tw/topcat/0805/TransactionScopePart1Scope.Complete_9398/ts002_thumb.jpg" width=494 border=0&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;小喵會寫兩段更改資料的語法，分別&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;將EmployeeID=1的LastName最後一個字加上【X】字元，這部分是應該可以過得 
&lt;LI&gt;小喵試著要把EmployeeID=9的FirstName設定為【ABC123456789】,從資料表Layout看出，FirstName欄位大小是10個字元，因此這個應該會出現錯誤&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;理想的狀況應該是，他會Rollback，讓1.的變化也回覆&lt;/P&gt;
&lt;P&gt;首先，要看一下TransactionScope的說明請參考以下鏈結&lt;/P&gt;
&lt;P&gt;&lt;A title=http://msdn.microsoft.com/zh-tw/library/system.transactions.transactionscope(VS.80).aspx href="http://msdn.microsoft.com/zh-tw/library/system.transactions.transactionscope(VS.80).aspx"&gt;http://msdn.microsoft.com/zh-tw/library/system.transactions.transactionscope(VS.80).aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;接著就是測試的程式碼：&lt;/P&gt;
&lt;P&gt;小喵把北風加入asp.net的專案中，在畫面上安排一個Button1，並且從伺服器總館中把Empolyee這個資料表拉到設計中，系統會自動產生Employee這個資料表的GridView與SqlDataSouce以及在Web.Config中，會把ConnectionString準備好。接著小喵雙擊Button1開始寫Button1的程式碼&lt;/P&gt;
&lt;P&gt;一開始，當然要Imports相關的NameSpace，在撰寫時，發現彈不出System.Transactions，於是小喵先把System.Transactions加入參考。然後在最上方加入Imports&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=wlWriterSmartContent id=scid:812469c5-0cb0-4c63-8c15-c81123a09de7:495afa39-1da0-4c3d-8149-84155e375444 style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;TEXTAREA class=vb name=code rows=6 cols=50&gt;Imports System
Imports System.Transactions
Imports System.Data
Imports System.Data.SqlClient&lt;/TEXTAREA&gt;&lt;/DIV&gt;&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=wlWriterSmartContent style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;接著就撰寫Button1 Click事件的內容，小喵依照MSDN上面的範例，撰寫以下的內容&lt;/DIV&gt;&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=wlWriterSmartContent style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;TEXTAREA class=vb name=code rows=6 cols=50&gt;        Using Scope As New TransactionScope
            Try

                Dim ConnStr As String = ConfigurationManager.ConnectionStrings("NORTHWNDConnectionString1").ConnectionString
                Using Conn As New SqlConnection(ConnStr)
                    Conn.Open()
                    Dim SqlTxt As String = ""
                    Dim Cmmd As SqlCommand

                    SqlTxt += " Update Employees "
                    SqlTxt += " Set LastName = LastName + 'X' "
                    SqlTxt += " Where EmployeeID = @EmployeeID "
                    SqlTxt += "  "
                    Cmmd = New SqlCommand(SqlTxt, Conn)
                    Cmmd.Parameters.AddWithValue("@EmployeeID", 1)
                    Cmmd.ExecuteNonQuery()
                    '---以上這一段理論上是可以正常通過的


                    '---以下這段因為超過欄位大小，應該會有Exception
                    SqlTxt = ""
                    SqlTxt += " Update Employees "
                    SqlTxt += " Set FirstName = 'ABC1234567890' "
                    SqlTxt += " Where EmployeeID = @EmployeeID "
                    SqlTxt += "  "

                    Cmmd = New SqlCommand(SqlTxt, Conn)
                    Cmmd.Parameters.AddWithValue("@EmployeeID", 9)
                    Cmmd.ExecuteNonQuery()

                End Using

            Catch ex As Exception
                Response.Write(ex.Message.ToString)

            End Try

            ' The Complete method commits the transaction. If an exception has been thrown,
            ' Complete is called and the transaction is rolled back.

            '設定交易完成
            Scope.Complete()


        End Using
        Me.GridView1.DataBind()&lt;/TEXTAREA&gt;&lt;/DIV&gt;&lt;/P&gt;
&lt;DIV class=wlWriterSmartContent style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;
&lt;P&gt;結果太令人意外了，竟然沒有把這兩段維護包在一個Transaction中，小喵從以往的經驗裡面，判斷，Scope.Complete()應該要在沒有Exception的狀況，才進行。很顯然的，他的位置不對，因此小喵覺得他的範例中註解的那句話不正確。小喵試著把他的位置調整一下，調整後如下：&lt;/P&gt;
&lt;P&gt;
&lt;DIV class=wlWriterSmartContent id=scid:812469c5-0cb0-4c63-8c15-c81123a09de7:796e6da3-cca0-4888-872d-bc1eee1f94ea style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;&lt;TEXTAREA class=vb name=code rows=6 cols=50&gt;        Using Scope As New TransactionScope
            Try

                Dim ConnStr As String = ConfigurationManager.ConnectionStrings("NORTHWNDConnectionString1").ConnectionString
                Using Conn As New SqlConnection(ConnStr)
                    Conn.Open()
                    Dim SqlTxt As String = ""
                    Dim Cmmd As SqlCommand

                    SqlTxt += " Update Employees "
                    SqlTxt += " Set LastName = LastName + 'X' "
                    SqlTxt += " Where EmployeeID = @EmployeeID "
                    SqlTxt += "  "
                    Cmmd = New SqlCommand(SqlTxt, Conn)
                    Cmmd.Parameters.AddWithValue("@EmployeeID", 1)
                    Cmmd.ExecuteNonQuery()
                    '---以上這一段理論上是可以正常通過的


                    '---以下這段因為超過欄位大小，應該會有Exception
                    SqlTxt = ""
                    SqlTxt += " Update Employees "
                    SqlTxt += " Set FirstName = 'ABC1234567890' "
                    SqlTxt += " Where EmployeeID = @EmployeeID "
                    SqlTxt += "  "

                    Cmmd = New SqlCommand(SqlTxt, Conn)
                    Cmmd.Parameters.AddWithValue("@EmployeeID", 9)
                    Cmmd.ExecuteNonQuery()

                End Using

                '正確的位置應該在這裡，也就是當有意外狀況的時候，應該要不能Scope.Complete()
                '設定交易完成
                Scope.Complete()


            Catch ex As Exception
                Response.Write(ex.Message.ToString)

            End Try

        End Using
        Me.GridView1.DataBind()&lt;/TEXTAREA&gt;&lt;/DIV&gt;&lt;/P&gt;
&lt;DIV class=wlWriterSmartContent style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; FLOAT: none; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;
&lt;P&gt;經過這樣位置調整後，終於有了預期的效果，當第二個維護發生狀況時，同時把第一個維護的結果Rollback了。因此請大家要使用TransactionScope的時候，&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;要特別注要安排Scope.Complete的位置要正確，才能達到預期的效果。&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;結論：&lt;/P&gt;
&lt;P&gt;使用TransactionScope用法相當簡單，只要宣告Scope，並把要維護的過程包起來，就能夠確保維護過程的交易(Transaction)完整性。不過使用時要&lt;STRONG&gt;特別特別注意Scope.Complete放的位置&lt;/STRONG&gt;，要在&lt;STRONG&gt;&lt;FONT color=#0000ff&gt;確定沒有Exception的狀況下，才使用Scope.Complete來讓Transaction進行Commit&lt;/FONT&gt;&lt;/STRONG&gt;。&lt;/P&gt;
&lt;P&gt;另外，TransactionScope不只是這樣而已，使用物件導向設計，在一個商業邏輯中用了數個物件維護資料，也可透過TransactionScope來確保交易的完整性，請看下一篇文章【&lt;A id=viewpost_ascx_TitleUrl title="Title of this entry." href="http://www.dotblogs.com.tw/topcat/archive/2008/05/15/3998.aspx"&gt;&lt;FONT color=#002c99&gt;確保交易的新利器(TransactionScope)初體驗-Part 2(物件維護的交易確保)&lt;/FONT&gt;&lt;/A&gt;】&lt;/P&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;img src ="http://blog.blueshop.com.tw/topcat/aggbug/55049.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>topcat</dc:creator><title>巢狀GridView範例(多筆訂單、訂單明細設計範例)錄影</title><link>http://blog.blueshop.com.tw/topcat/archive/2008/04/30/54924.aspx</link><pubDate>Wed, 30 Apr 2008 15:07:00 GMT</pubDate><guid>http://blog.blueshop.com.tw/topcat/archive/2008/04/30/54924.aspx</guid><wfw:comment>http://blog.blueshop.com.tw/topcat/comments/54924.aspx</wfw:comment><comments>http://blog.blueshop.com.tw/topcat/archive/2008/04/30/54924.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.blueshop.com.tw/topcat/comments/commentRss/54924.aspx</wfw:commentRss><trackback:ping>http://blog.blueshop.com.tw/topcat/services/trackbacks/54924.aspx</trackback:ping><description>&lt;P&gt;有時候希望多筆顯示訂單，但是訂單Orders、訂單明細OrderDetail可能分屬於不同的資料表中，因此如果多筆顯示的時候，就可以使用這個【巢狀GridView】的技巧。&lt;/P&gt;
&lt;P&gt;這個範例會說明兩個東西：&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;DropDownList與GridView互動：使用DropDownList顯示員工，當挑選了某個員工，則透過GridView顯示該員工的相關訂單內容。 
&lt;LI&gt;巢狀GridView的設計：透過TemplateField的應用，將訂單明細用第二個GridView顯示在GridView1中的TemplateField中。 
&lt;LI&gt;透過RowDataView使用欄位名稱取得GridView某欄位的內容&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;方式主要是透過外部的GridView1的RowDataBound事件，為訂單Orders的每個Row設定他內部的SqlDataSouce資料來源是GridView的哪個欄位。相關程式碼如下：&lt;/P&gt;
&lt;P&gt;&lt;TEXTAREA class=vb name=code rows=6 cols=50&gt;    Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
        '判斷是資料的Row才處理
        If e.Row.RowType = DataControlRowType.DataRow Then
            '透過FindControl取得裡面的SqlDataSouce物件
            Dim sds1 As SqlDataSource = CType(e.Row.Cells(1).FindControl("sdsOrderDetail"), SqlDataSource)

            '透過使用DataRowView，能夠用欄位名稱取得欄位的資料
            Dim rw As System.Data.DataRowView = CType(e.Row.DataItem, System.Data.DataRowView)
            '指定SelectParameter的內容
            sds1.SelectParameters(0).DefaultValue = rw.Item("OrderID").ToString

        End If
    End Sub &lt;/TEXTAREA&gt;&lt;/P&gt;
&lt;P&gt;執行結果畫面如下：&lt;/P&gt;
&lt;P&gt;&lt;A href="http://files.dotblogs.com.tw/topcat/0804/GridView_D024/GVGV01_2.jpg"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=184 alt=GVGV01 src="http://files.dotblogs.com.tw/topcat/0804/GridView_D024/GVGV01_thumb.jpg" width=244 border=0&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;相關程式碼如下：&lt;/P&gt;
&lt;P&gt;&lt;A href="http://vip2.blueshop.com.tw/topcat/DEMO/GVGV/GVGV.zip" target=_blank&gt;&lt;FONT color=#002c99&gt;http://vip2.blueshop.com.tw/topcat/DEMO/GVGV/GVGV.zip&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#002c99&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;設計過程錄影如下超連結：&lt;/P&gt;
&lt;P&gt;&lt;A title=http://vip2.blueshop.com.tw/topcat/DEMO/GVGV/GVGV.html href="http://vip2.blueshop.com.tw/topcat/DEMO/GVGV/GVGV.html" target=_blank&gt;&lt;FONT color=#002c99&gt;http://vip2.blueshop.com.tw/topcat/DEMO/GVGV/GVGV.html&lt;/FONT&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src ="http://blog.blueshop.com.tw/topcat/aggbug/54924.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>topcat</dc:creator><title>(DropDownList 動態結合 GridView)及(GridView合計)範例</title><link>http://blog.blueshop.com.tw/topcat/archive/2008/04/25/54894.aspx</link><pubDate>Fri, 25 Apr 2008 10:27:00 GMT</pubDate><guid>http://blog.blueshop.com.tw/topcat/archive/2008/04/25/54894.aspx</guid><wfw:comment>http://blog.blueshop.com.tw/topcat/comments/54894.aspx</wfw:comment><comments>http://blog.blueshop.com.tw/topcat/archive/2008/04/25/54894.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blog.blueshop.com.tw/topcat/comments/commentRss/54894.aspx</wfw:commentRss><trackback:ping>http://blog.blueshop.com.tw/topcat/services/trackbacks/54894.aspx</trackback:ping><description>&lt;P&gt;在這篇範例裡面，資料庫使用北風資料庫，主要講兩個東西，其實都還蠻基本的&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;DropDownList動態結合GridView: 
&lt;UL&gt;
&lt;LI&gt;使用DropDownList列出訂單編號(Orders.OrderID)，當挑選了DropDownList之後，GridView依照DropDownList的訂單編號，顯示該訂單的細部資料(Order Details)&lt;/LI&gt;&lt;/UL&gt;
&lt;LI&gt;透過 GridView的RowDataBound事件，來進行計算ATM合計的工作&lt;/LI&gt;&lt;/OL&gt;&lt;PRE class=csharpcode&gt;接著來看運作的畫面會是如何&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;一開始出現DropDownList，預設項目【請選擇】，如下圖&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;&lt;A href="http://files.dotblogs.com.tw/topcat/0804/DropDownListGridViewGridView_E1EA/GVS001_2.jpg"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=45 alt=GVS001 src="http://files.dotblogs.com.tw/topcat/0804/DropDownListGridViewGridView_E1EA/GVS001_thumb.jpg" width=97 border=0&gt;&lt;/A&gt; &lt;/PRE&gt;&lt;PRE class=csharpcode&gt;選擇其中之一訂單編號，如下圖&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;&lt;A href="http://files.dotblogs.com.tw/topcat/0804/DropDownListGridViewGridView_E1EA/GVS002_2.jpg"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=113 alt=GVS002 src="http://files.dotblogs.com.tw/topcat/0804/DropDownListGridViewGridView_E1EA/GVS002_thumb.jpg" width=91 border=0&gt;&lt;/A&gt; &lt;/PRE&gt;&lt;PRE class=csharpcode&gt;出現該訂單的內容，並在最後顯是合計&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;&lt;A href="http://files.dotblogs.com.tw/topcat/0804/DropDownListGridViewGridView_E1EA/GVS003_2.jpg"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=113 alt=GVS003 src="http://files.dotblogs.com.tw/topcat/0804/DropDownListGridViewGridView_E1EA/GVS003_thumb.jpg" width=244 border=0&gt;&lt;/A&gt; &lt;/PRE&gt;&lt;PRE class=csharpcode&gt;相關程式內容如下&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;畫面部分&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;&lt;TEXTAREA class=xml name=code rows=6 cols=50&gt;        &amp;lt;asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" 
            DataSourceID="SqlDataSource1" DataTextField="OrderID" DataValueField="OrderID"&amp;gt;
        &amp;lt;/asp:DropDownList&amp;gt;
        &amp;lt;br /&amp;gt;
        &amp;lt;asp:SqlDataSource ID="SqlDataSource1" runat="server" 
            ConnectionString="&amp;lt;%$ ConnectionStrings:ConnectionString %&amp;gt;" 
            SelectCommand="SELECT DISTINCT [OrderID] FROM [Orders] ORDER BY [OrderID]"&amp;gt;
        &amp;lt;/asp:SqlDataSource&amp;gt;
        &amp;lt;br /&amp;gt;
        &amp;lt;asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
            DataKeyNames="OrderID,ProductID" DataSourceID="SqlDataSource2" 
            ShowFooter="True"&amp;gt;
            &amp;lt;Columns&amp;gt;
                &amp;lt;asp:BoundField DataField="OrderID" HeaderText="OrderID" ReadOnly="True" 
                    SortExpression="OrderID" /&amp;gt;
                &amp;lt;asp:BoundField DataField="ProductID" HeaderText="ProductID" ReadOnly="True" 
                    SortExpression="ProductID" /&amp;gt;
                &amp;lt;asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" 
                    SortExpression="UnitPrice"&amp;gt;
                    &amp;lt;ItemStyle HorizontalAlign="Right" /&amp;gt;
                &amp;lt;/asp:BoundField&amp;gt;
                &amp;lt;asp:BoundField DataField="Quantity" HeaderText="Quantity" 
                    SortExpression="Quantity"&amp;gt;
                    &amp;lt;ItemStyle HorizontalAlign="Right" /&amp;gt;
                &amp;lt;/asp:BoundField&amp;gt;
                &amp;lt;asp:BoundField DataField="Discount" HeaderText="Discount" 
                    SortExpression="Discount"&amp;gt;
                    &amp;lt;ItemStyle HorizontalAlign="Right" /&amp;gt;
                &amp;lt;/asp:BoundField&amp;gt;
                &amp;lt;asp:BoundField DataField="AMT" HeaderText="AMT" ReadOnly="True" 
                    SortExpression="AMT"&amp;gt;
                    &amp;lt;ItemStyle HorizontalAlign="Right" /&amp;gt;
                &amp;lt;/asp:BoundField&amp;gt;
            &amp;lt;/Columns&amp;gt;
        &amp;lt;/asp:GridView&amp;gt;
        &amp;lt;br /&amp;gt;
        &amp;lt;asp:SqlDataSource ID="SqlDataSource2" runat="server" 
            ConnectionString="&amp;lt;%$ ConnectionStrings:ConnectionString %&amp;gt;" 
            SelectCommand="SELECT OrderID, ProductID, UnitPrice, Quantity, Discount, UnitPrice * Quantity - Discount AS AMT FROM [Order Details] WHERE (OrderID = @OrderID)"&amp;gt;
            &amp;lt;SelectParameters&amp;gt;
                &amp;lt;asp:ControlParameter ControlID="DropDownList1" Name="OrderID" 
                    PropertyName="SelectedValue" /&amp;gt;
            &amp;lt;/SelectParameters&amp;gt;
        &amp;lt;/asp:SqlDataSource&amp;gt;
    &lt;/TEXTAREA&gt;&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;CodeFile部分:&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;&lt;TEXTAREA class=vb name=code rows=6 cols=50&gt;Partial Class _Default
    Inherits System.Web.UI.Page

    Dim SumAMT As Integer = 0   '設定全域變數記錄合計

    Protected Sub DropDownList1_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles DropDownList1.DataBound
        If Not IsPostBack Then
            Dim tLItm As New ListItem("請選擇", "")
            Me.DropDownList1.Items.Insert(0, tLItm)
        End If
    End Sub

    Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
        If e.Row.RowType = DataControlRowType.DataRow Then
            e.Row.Cells(5).Text = FormatNumber(e.Row.Cells(5).Text, 2)
            SumAMT += CInt(e.Row.Cells(5).Text.ToString)
        End If
        If e.Row.RowType = DataControlRowType.Footer Then
            e.Row.Cells(5).Text = FormatNumber(SumAMT, 2)
        End If
    End Sub
End Class&lt;/TEXTAREA&gt;&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;&lt;PRE class=csharpcode&gt;&amp;nbsp;&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;原始碼下載：&lt;A href="http://cid-8b18e2aead63b0da.skydrive.live.com/self.aspx/%e7%a8%8b%e5%bc%8f%e7%af%84%e4%be%8b%e8%88%87%e5%8b%95%e7%95%ab%e8%aa%aa%e6%98%8e/GridViewSum/tGVS.zip" target=_blank&gt;&lt;FONT color=#002c99&gt;tGVS.zip(0.6MB)&lt;/FONT&gt;&lt;/A&gt; (版本：VS2008)&lt;/PRE&gt;&lt;PRE class=csharpcode&gt;操作過程錄影下載： &lt;A href="http://cid-8b18e2aead63b0da.skydrive.live.com/self.aspx/%e7%a8%8b%e5%bc%8f%e7%af%84%e4%be%8b%e8%88%87%e5%8b%95%e7%95%ab%e8%aa%aa%e6%98%8e/GridViewSum/tGVSum.zip" target=_blank&gt;&lt;FONT color=#002c99&gt;tGVSum.zip(9.5MB)&lt;/FONT&gt;&lt;/A&gt;&lt;/PRE&gt;&lt;/PRE&gt;&lt;img src ="http://blog.blueshop.com.tw/topcat/aggbug/54894.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>topcat</dc:creator><title>如何從DataTable中取出Distinct的資料</title><link>http://blog.blueshop.com.tw/topcat/archive/2007/10/23/53011.aspx</link><pubDate>Tue, 23 Oct 2007 14:30:00 GMT</pubDate><guid>http://blog.blueshop.com.tw/topcat/archive/2007/10/23/53011.aspx</guid><wfw:comment>http://blog.blueshop.com.tw/topcat/comments/53011.aspx</wfw:comment><comments>http://blog.blueshop.com.tw/topcat/archive/2007/10/23/53011.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blog.blueshop.com.tw/topcat/comments/commentRss/53011.aspx</wfw:commentRss><trackback:ping>http://blog.blueshop.com.tw/topcat/services/trackbacks/53011.aspx</trackback:ping><description>&lt;P&gt;當我們已經把資料放入DataTable之後，我們想從裡面取出類似SQL DISTINCT的資料(不重複的資料)，這個時候我們沒辦法像SQL一樣直著下語法得到。&lt;/P&gt;
&lt;P&gt;我們利用DataView的ToTable的方法中，有個參數是設定是否要distinct資料，透過這樣的方式就能夠得到我們想要的效果，以下是範例程式&lt;/P&gt;
&lt;P&gt;範例中假設已經取得資料，要把LastName這個欄位做Distinct&lt;/P&gt;
&lt;P&gt;&lt;TEXTAREA class=vb style="WIDTH: 692px; HEIGHT: 100px" name=code rows=6 cols=81&gt;Dim tmpView As DataView = Dt.DefaultView
Dim tmpTable as DataTable = tmpView.ToTable("TmpTable1",True,"LastName")&lt;/TEXTAREA&gt;&lt;/P&gt;&lt;img src ="http://blog.blueshop.com.tw/topcat/aggbug/53011.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>topcat</dc:creator><title>RecordSet轉DataSet</title><link>http://blog.blueshop.com.tw/topcat/archive/2007/08/24/52132.aspx</link><pubDate>Fri, 24 Aug 2007 09:55:00 GMT</pubDate><guid>http://blog.blueshop.com.tw/topcat/archive/2007/08/24/52132.aspx</guid><wfw:comment>http://blog.blueshop.com.tw/topcat/comments/52132.aspx</wfw:comment><comments>http://blog.blueshop.com.tw/topcat/archive/2007/08/24/52132.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.blueshop.com.tw/topcat/comments/commentRss/52132.aspx</wfw:commentRss><trackback:ping>http://blog.blueshop.com.tw/topcat/services/trackbacks/52132.aspx</trackback:ping><description>&lt;P&gt;上一篇&lt;A href="http://blog.blueshop.com.tw/topcat/archive/2007/08/24/52128.aspx" target=_blank&gt;從DataSet轉Recordset&lt;/A&gt;後，接著就是另一個方向，從RecordSet轉DataSet&lt;/P&gt;
&lt;P&gt;這個部份就沒有像上一篇那樣辛苦，可以直接透過DataAdapter的Fill來處理&lt;/P&gt;
&lt;P&gt;程式需要Imports三個NameSpace&lt;BR&gt;Imports ADODB&lt;BR&gt;Imports System.Data&lt;BR&gt;Imports System.Data.OleDb&lt;/P&gt;
&lt;P&gt;相關的程式如下&lt;/P&gt;
&lt;P&gt;&lt;TEXTAREA class=vb style="WIDTH: 664px; HEIGHT: 100px" name=code rows=6 cols=78&gt;    Private Function Rs2Ds(ByVal Rs As Recordset) As DataSet
        Dim Da As New OleDbDataAdapter
        Da.Fill(Ds, Rs, "Table1")
        Return Ds
    End Function
&lt;/TEXTAREA&gt;&lt;/P&gt;&lt;img src ="http://blog.blueshop.com.tw/topcat/aggbug/52132.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>topcat</dc:creator><title>DataSet轉RecordSet的Function</title><link>http://blog.blueshop.com.tw/topcat/archive/2007/08/24/52128.aspx</link><pubDate>Fri, 24 Aug 2007 08:41:00 GMT</pubDate><guid>http://blog.blueshop.com.tw/topcat/archive/2007/08/24/52128.aspx</guid><wfw:comment>http://blog.blueshop.com.tw/topcat/comments/52128.aspx</wfw:comment><comments>http://blog.blueshop.com.tw/topcat/archive/2007/08/24/52128.aspx#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://blog.blueshop.com.tw/topcat/comments/commentRss/52128.aspx</wfw:commentRss><trackback:ping>http://blog.blueshop.com.tw/topcat/services/trackbacks/52128.aspx</trackback:ping><description>&lt;P&gt;小喵目前正值.NET與ASP的混用期&lt;/P&gt;
&lt;P&gt;因此目前撰寫的元件，可能會被以前的ASP程式呼叫到，於是這衍生了一個問題&lt;BR&gt;以前的ASP看不懂DataSet，以前的VB6元件也看不懂DataSet&lt;/P&gt;
&lt;P&gt;因此小喵寫了個小小的Function來轉換，相關程式碼如下&lt;/P&gt;
&lt;P&gt;&lt;TEXTAREA class=vb style="WIDTH: 698px; HEIGHT: 100px" name=code rows=6 cols=82&gt;    Public Function ChgDs2Rs(ByVal Ds As DataSet) As Object
        '*************************************************************************
        '**     撰寫者：                撰寫日期：2007/6/4
        '**     用途：  1.DataSet 轉 RecordSet
        '**     做法：
        '**             1.
        '**     注意事項：
        '**             1.
        '**             2.
        '**     維護記錄：
        '**         維護者：姓名(員工代號)     維護日期：日期
        '**         維護項目：
        '**                 1.
        '**                 2.
        '**         做法：  1.
        '**                 2.
        '**         注意事項：
        '**                 1.
        '*************************************************************************
        Try
            Dim rs As Object = CreateObject("ADODB.Recordset")

            If Ds.Tables(0).Rows.Count &amp;gt; 0 Then
                Dim x, y As Integer
                Dim ColName As String = ""

                For x = 0 To Ds.Tables(0).Columns.Count - 1
                    ColName = Ds.Tables(0).Columns(x).ColumnName
                    rs.Fields.Append(ColName, 200, 255)
                Next
                rs.Open()

                For y = 0 To Ds.Tables(0).Rows.Count - 1
                    rs.AddNew()
                    For x = 0 To Ds.Tables(0).Columns.Count - 1
                        If IsDBNull(Ds.Tables(0).Rows(y).Item(x)) Then
                            rs.Fields(x).Value = ""
                        Else
                            rs.Fields(x).Value = Ds.Tables(0).Rows(y).Item(x)
                        End If
                    Next
                Next
            End If

            Return rs

        Catch ex As Exception
            Throw New Exception(ex.Message.ToString)

        Finally
            'Ds.Dispose()

        End Try
    End Function
&lt;/TEXTAREA&gt;&lt;/P&gt;&lt;img src ="http://blog.blueshop.com.tw/topcat/aggbug/52128.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>