解決:C#除非指定UpdateCommand,否則數據源SqlDataSource不支持更新操作


今天在做東西,更新數據庫,數據庫更新成功了,可是sqldatasource卻求支持,於是我找了所有可能的原因,最后終於解決了。就是更新完數據庫一定要記得更新sqldatasource!雖然不是什么大錯,但是改了,頁面才會百分百不出錯,看着也舒服些么!下面就是更新它的一個簡單舉例:

SqlDataSource1.UpdateCommand = "UPDATE PlayList SET PlayTime="+time2+", PlayBorder="+border+"";

下面來看看原因吧:
SqlDataSource控件 

SqlDataSource控件是一個數據源控件,代表與一個關系型數據存儲(諸如SQL Server或Oracle或任何一個可以通過OLE DB或ODBC橋梁訪問的數據源)的連接。

我們使用兩個主要屬性建立數據存儲的連接:ConnectionString和ProviderName。前一個屬性表示連接字符串,包含了打開與底層引擎會話所需的足夠信息。后一個屬性規定此操作使用的ADO.NET托管提供程序的命名空間。ProviderName屬性默認為System.Data.SqlClient,這表示默認的數據存儲是SQL Server。例如,要瞄准一個OLE DB提供程序,則使用System.Data.OleDb字符串。

該控件既可以使用數據適配器也可以使用命令對象檢索數據。根據我們的選擇,獲取的數據將被封裝到一個DataSet對象或一個數據閱讀器中。如下代碼片斷說明了激活一個綁定到一個SQL Server數據庫的SQL數據源控件所需的最少代碼:

<asp:SqlDataSource runat="server" ID="MySqlSource" 

    ProviderName='<%$ ConnectionStrings:LocalNWind.ProviderName %>'

    ConnectionString='<%$ ConnectionStrings:LocalNWind %>'

    SelectCommand="SELECT * FROM employees" />

<asp:DataGrid runat="server" ID="grid" DataSourceID="MySqlSource" />

1. SqlDataSource控件的編程接口
表9.10列出的屬性組提供了關聯的視圖類所支持的數據操作。



表9.10 配置數據操作的屬性
屬性組
描述

DeleteCommand, DeleteParameters,

DeleteCommandType
獲得或設置用來刪除底層數據存儲中的數據行的SQL語句、相關參數以及類型(文本或存儲過程)。

FilterExpression, FilterParameters
獲得或設置用來創建使用Select命令獲取的數據之上的過濾器的字符串(和相關參數)。只有當控件通過DataSet管理數據時才起作用。

InsertCommand, InsertParameters,

InsertCommandType
獲得或設置用來在底層數據存儲中插入新行的SQL語句、相關參數和類型(文本或存儲過程)。

SelectCommand, SelectParameters,

SelectCommandType
獲得或設置用來從底層數據存儲中獲取數據的SQL語句、相關參數和類型(文本或存儲過程)。

SortParameterName
獲得或設置一個命令的存儲過程將用來存儲數據的一個輸入參數的名稱。(這種情況下的命令必須是存儲過程。)如果缺少該參數,則會引起一個異常。

UpdateCommand, UpdateParameters,

UpdateCommandType
獲得或設置用來更新底層數據存儲中的數據行的SQL語句、相關參數和類型(文本或存儲過程)。


每個命令屬性都是一個字符串,包含將要使用的SQL文本。命令可以有選擇地包含關聯參數集中列出的參數。托管提供程序及其底層的關系引擎決定SQL要使用的確切語法以及嵌入參數的語法。例如,如果數據源控件指向SQL Server,則命令參數名必須以@symbol為前綴。如果目標數據源是一個OLE DB提供程序,則參數是無名的,用一個?占位符符號標識,並且按位置進行定位。如下代碼片斷展示了一個更復雜的數據源控件,其中啟用了參數化刪除和更新命令:

<asp:SqlDataSource runat="server" ID="MySqlSource"

    ConnectionString='<%$ ConnectionStrings:LocalNWind %>'

    SelectCommand="SELECT * FROM employees"

    UpdateCommand="UPDATE employees SET lastname=@lname"

    DeleteCommand="DELETE FROM employees WHERE employeeid=@TheEmp"

    FilterExpression="employeeid > 3">

    <!-- parameters go here -->

</asp:SqlDataSource> 

FilterExpression屬性適用的語法與DataView類的RowFilter屬性適用的語法相同,而后者又類似於SQL WHERE子句使用的語法。如果FilterExpression需要是參數化的,則可以通過FilterParameters集合指明參數。只有在DataSourceMode設置為DataSet時才能啟用過濾功能。

注意    注意過濾器表達式和Select命令上的參數之間的區別。該命令上的參數影響數據存儲返回的結果集;而過濾器表達式限制通過Select命令返回的結果集的顯示內容。

表9.11詳細描述了SqlDataSource類的其他操作屬性。該列表沒有包括與緩存相關的屬性,稍后再介紹這些屬性。



表9.11 SqlDataSource類的其他屬性
屬性
描述

CancelSelectOnNullParameter
指示如果一個參數等於null是否撤銷數據檢索操作。默認值為true。

ConflictDetection
決定該控件在一次刪除或更新操作期間應如何處理數據沖突。在默認情況下,同時發生的變更被覆蓋。

ConnectionString
連接到數據庫的連接字符串。

DataSourceMode
指示應如何返回數據:通過DataSet還是通過數據閱讀器。

OldValuesParameterFormatString
獲得或設置一個格式字符串,該格式字符串應用於傳遞給Delete或Update方法的任何參數的名稱。

ProviderName
指示將要使用的ADO.NET托管提供程序的命名空間。


有趣的是,這些屬性中有很多映射了實際視圖類上定義的相同屬性,如前面的圖9.10所示。

SqlDataSource對象有幾個方法和事件,在大多數情況下所有的數據源組件都有這些方法和事件。其中方法包括Delete, Insert, Select和Update,並且它們是作為底層數據源視圖類的對應方法的惟一封裝器實現的。這些事件成對存在:Deleting/Deleted、Inserting/Inserted、Selecting/Selected和Updating/Updated,並且在上述方法之前和之后激發。過濾操作的開始通過Filtering事件發出信號。

如前所述,ASP.NET 2.0特有的控件是惟一真正地利用數據源控件的能力的控件。因而,后面兩章專門介紹GridView, DetailsView和FormView控件,到時將會看到大量示例代碼,它們說明了如何使用SqlDataSource控件進行選擇、更新、分頁和排序。在本章中,我們將花更多的時間來討論該控件的其他特征,這些特征特別適合在實際應用中使用。

2. 聲明性參數
每個命令屬性都有自己的參數集——ParameterCollection集合類的一個實例。ASP.NET 2.0支持不少參數類型,如表9.12所示。

表9.12 ASP.NET 2.0中的參數類型
參數
描述

ControlParameter
從一個服務器控件的任何公共屬性獲得該參數值。

CookieParameter
根據指定的HTTP cookie的內容設置參數值。

FormParameter
從HTTP請求窗體的指定輸入字段中獲取該參數值。

Parameter
獲取由代碼分配的參數值。

ProfileParameter
從根據應用程序的個性化機制創建的配置文件對象中的指定屬性獲取該參數值。

QueryStringParameter
從請求查詢字符串中的指定變量獲取該參數值。

SessionParameter
根據指定的會話狀態槽的內容設置該參數值。


每個參數類都有一個Name屬性以及它的作用和實現特有的屬性集。為了理解數據源控件中的聲明性參數,讓我們看看如下代碼:

<asp:SqlDataSource runat="server" ID="MySource"

    ConnectionString='<%$ ConnectionStrings:LocalNWind %>'

    SelectCommand="SELECT * FROM employees WHERE employeeid > @MinID">

    <SelectParameters>

        <asp:ControlParameter Name="MinID" ControlId="EmpID"

            PropertyName="Text" />

    </SelectParameters>

</asp:SqlDataSource> 

該查詢包含一個名為@MinID的占位符。該數據源控件用ControlParameter對象返回的信息自動地填充該占位符。控件參數的值由給定控件上的給定屬性所決定。PropertyName屬性規定了該屬性的名稱;而該控件的ID在ControlId屬性中。為了使前面的代碼起作用,頁面開發人員必須保證該頁面包含一個具有給定的ID和屬性的控件;否則,拋出一個異常。在本例中,EmpID控件上的Text屬性的值被用作匹配參數的值。

形參(命令文本中的占位符)和實際值之間的綁定,取決於底層的托管提供程序如何處理和辨認參數。如果提供程序類型支持有名的參數(象SQL Server和Oracle那樣),則這種綁定涉及將占位符的名稱與參數的名稱進行匹配。否則,這種匹配是基於位置的。因此,第1個占位符綁定到第1個參數,以此類推。這就是使用OLE DB訪問數據時發生的情況。

3. 沖突檢測
SqlDataSource控件能夠以兩種方法之一有選擇地執行數據庫侵入的操作(刪除和更新)。數據源控件與數據綁定控件相聯系,因此,同時讀取數據,也許還要在客戶端進行修改,然后進行更新,這種思想並不是牽強的。在多個用戶擁有對數據庫的讀/寫訪問的情況下,如果他們企圖操作的記錄同時被修改了,則更新/刪除方法的行為應怎樣呢?

SqlDataSource控件使用ConflictDetection屬性確定在執行更新和刪除操作時要做什么。該屬性被聲明為ConflictOptions枚舉類型;其默認值是OverwriteChanges,這就是說,無論該行中的值自上一次被讀取以來有沒有發生變化,任何侵入操作都會發生變化。另一個值是CompareAllValues,它只是確保SqlDataSource控件將從數據庫讀取得原始數據,傳給底層視圖類的Delete或Update方法。

除非這樣編寫刪除或更新語句,即如果該行中的數據不匹配最初讀取的數據,則命令失敗,否則改變ConflictDetection的值不會產生任何顯著效果,注意到這一點是重要的。為做到這一點,應如下面這樣定義命令:

UPDATE employees SET firstname=@firstname

WHERE employeeid=@employeeid AND firstname=@original_firstname

換句話說,我們必須顯式地向命令添加一個額外的子句,檢查正被修改的字段的當前值是否仍然匹配最初讀取的值。這樣,多個用戶同時輸入的中間變更使WHERE子句失敗,從而使命令失敗。我們自己負責調整命令文本;把ConflictDetection設置為CompareAllValues是不夠的。

如何格式化表示舊值的參數的名稱?SqlDataSource控件使用OldValuesParameterFormatString屬性格式化這些參數名。默認值是original_{0}。

如果使用CompareAllValues選項,則可以處理數據源控件上的Deleted或Updated事件,以檢查多少行受到影響。如果該操作沒有影響任何記錄,則可能會發生並發違規(concurrency violation):

void OnUpdated(object sender, SqlDataSourceStatusEventArgs e)

{

    if (e.AffectedRows == 0) {

    ...

    }

}

4. 緩存行為
一個數據綁定控件與它的數據源組件之間的數據綁定是自動完成的,並在由數據綁定控件引起的每次頁面回發時發生。假設一個頁面有網格、一個數據源控件和一個按鈕。如果以編輯模式打開該網格,則Select命令運行;如果單擊該按鈕(在數據綁定控件的邊界之外),則根據視圖狀態重建該網格的UI,並且不會運行任何Select語句。

為了在每次回發時保存一個查詢,可以要求數據源控件緩存給定期間內的結果集。在數據被緩存的時間里,Select方法從緩存(而不是底層數據庫)中檢索數據。在該緩存期滿時,Select方法從底層數據檢索數據,並新數據存回到緩存中。SqlDataSource的緩存行為由表9.13中的屬性所控制。

表9.13 SqlDataSource上的緩存屬性
屬性
描述

CacheDuration
指示數據應當在緩存中保留多久(以秒為單位)。

CacheExpirationPolicy
指示緩存期限是絕對的還是可調整的。如果是絕對的,則在規定的秒數之后使緩存中的數據無效。如果是可調整的,則使那些在指定期限內沒有用過的數據無效。

CacheKeyDependency
指示用戶定義的緩存鍵的名稱,該緩存鍵鏈接到數據源控件創建的所有緩存項。通過終止該鍵,可以清楚該控件的緩存。

EnableCaching
啟用或禁用緩存支持。

SqlCacheDependency
獲得或設置一個用分號分隔的字符串,指示哪些數據庫和表用於SQL Server緩存依賴。


SelectCommand、ConnectionString和SelectParameters的每種不同組合創建一個緩存項。如果多個SqlDataSource控件正好裝載相同數據庫中的相同數據,則它們可以共享相同的緩存項。通過CacheKeyDependency屬性可以控制由數據源控件管理的緩存項。如果該屬性設置為非null字符串,則強制SqlDataSource控件在用戶定義的鍵和該控件創建的所有緩存項之間建立依賴性。這時,要清除該控件的緩存,只需給依賴鍵分配一個新值:

Cache["ClearAll"] = anyInitializationValue;

SqlDataSource1.CacheKeyDependency = "ClearAll";

...

Cache["ClearAll"] = anyOtherValue;

SqlDataSource控件只有在DataSet模式下工作時才能緩存數據。如果DataSourceMode設置為DataReader,並且緩存被啟用,則會得到一個異常。

最后,SqlCacheDependency屬性將SqlDataSource控件緩存的數據與指定數據庫表(通常與提供緩存數據的表是同一個表)的內容聯系起來:

<asp:SqlDataSource ID="SqlDataSource1" runat="server"

CacheDuration="1200"

ConnectionString="<%$ ConnectionStrings:LocalNWind %>"

EnableCaching="true"

SelectCommand="SELECT * FROM employees"

SqlCacheDependency="Northwind:Employees"> 

</asp:SqlDataSource>


免責聲明!

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



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