LinqDataSource 控制項可將資料控制項連接到各種資料來源。這些資料來源包括資料庫資料、資料來源類別以及記憶體中集合。LinqDataSource 控制項可針對這些類型的資料來源,指定和資料庫類似的擷取工作 (選取、篩選、分組及排序)。您也可以針對資料庫資料表來指定修改工作 (更新、刪除及插入)。
您可以將 LinqDataSource 控制項連接到儲存在公用欄位或屬性內的各種資料集合。所有資料來源在執行資料作業時所用的宣告式標記及程式碼都是相同的。您與資料庫資料表或資料集合 (如陣列) 中的資料互動時,不必使用不同的語法。
如需 LinqDataSource 控制項的簡介,請參閱逐步解說:使用 LinqDataSource 和 DetailsView 控制項擷取、更新、插入和刪除資料。
連接到資料庫的資料
連接到記憶體中集合的資料
連接到記憶體中資料集合 (如陣列) 時,請將 ContextTypeName 屬性設定成集合所屬類別的名稱。將 TableName 屬性設定成集合本身的名稱。
下列範例顯示包含字串值陣列的類別。
Public Class MovieLibrary
Dim _availableGenres() As String = {"Comedy", "Drama", "Romance"}
Public ReadOnly Property AvailableGenres() As String()
Get
Return _availableGenres
End Get
End Property
End Class
public class MovieLibrary
{
string[] _availableGenres = { "Comedy", "Drama", "Romance" };
public MovieLibrary()
{
}
public string[] AvailableGenres
{
get
{
return _availableGenres;
}
}
}
下列範例顯示 LinqDataSource 控制項,該控制項會從前一個範例中的類別讀取影片類型的清單。若要擷取類型的陣列,請將 ContextTypeName 屬性設定為 MovieLibrary,並將 TableName 屬性設定為 AvailableGenres。
<asp:LinqDataSource
ContextTypeName="MovieLibrary"
TableName="AvailableGenres"
ID="LinqDataSource1"
runat="server">
</asp:LinqDataSource>搭配資料繫結控制項使用 LinqDataSource 控制項
若要顯示 LinqDataSource 控制項中的資料,您可以將資料繫結控制項繫結到 LinqDataSource 控制項。例如,把 DetailsView 控制項、GridView 控制項或 ListView 控制項繫結到 LinqDataSource 控制項。做法是將資料繫結控制項的 DataSourceID 屬性設定成 LinqDataSource 控制項的 ID。下列範例中的 GridView 控制項即可顯示 LinqDataSource 控制項中的所有資料。
<asp:LinqDataSource
runat="server"
ContextTypeName="AdventureWorksDataContext"
TableName="Contacts"
ID="LinqDataSource1">
</asp:LinqDataSource>
<asp:GridView
ID="GridView1"
runat="server"
DataSourceID="LinqDataSource1" >
</asp:GridView>資料繫結控制項會自動建立使用者介面來顯示 LinqDataSource 控制項中的資料。它也會提供資料排序及資料分頁所需的介面。啟用資料修改功能時,資料繫結控制項會提供讓您更新、插入及刪除記錄的介面。
您可以將資料繫結控制項設定成不要自動產生資料控制項欄位,以限制要顯示的資料 (屬性)。之後,您就能在資料繫結控制項中明確定義這些欄位。LinqDataSource 控制項會擷取所有屬性,但資料繫結控制項僅顯示您指定的屬性。下列範例中的 GridView 控制項只顯示 AdventureWorks 資料庫裡 [產品] 資料表中的 Name 及 StandardCost 屬性。AutoGenerateColumns 屬性設定為 false。
<asp:LinqDataSource
ContextTypeName="AdventureWorksDataContext"
TableName="Products"
ID="LinqDataSource1"
runat="server">
</asp:LinqDataSource>
<asp:GridView
DataSourceID="LinqDataSource1"
AutoGenerateColumns="false"
ID="GridView1"
runat="server">
<Columns>
<asp:BoundField DataField="Name" />
<asp:BoundField DataField="StandardCost" />
</Columns>
</asp:GridView>如果要限制查詢時要傳回哪些屬性,請設定 LinqDataSource 控制項的 Select 屬性來定義要傳回的屬性。
比較 LinqDataSource 控制項與其他資料來源控制項
選取資料
如果您沒有指定 LinqDataSource 控制項之 Select 屬性的值,則會擷取資料來源類別中的所有屬性。例如,LinqDataSource 控制項會針對資料庫資料表的每一個資料行傳回一個值。
您可以將 Select 屬性設定成您要的屬性名稱,即可限制要從資料來源擷取哪些屬性。如果只想傳回一個屬性,請將 Select 屬性設定為該屬性。例如,您只想傳回資料庫資料表裡 City 資料行中的值,則請將 Select 屬性設定為 City。LinqDataSource 控制項會傳回一個 List<(Of <(T>)>) 集合,其中包含該屬性中正確輸入的項目。如果 City 屬性是以文字 (字串) 輸入,則選取 City 屬性便會傳回字串值的 List<(Of <(T>)>) 集合。
如果只想擷取資料類別中的某些屬性,請用 Select 屬性中的 new 功能,並指定要傳回的資料行。您將動態建立一個類別,其中只包含您已指定的屬性,因此 new 功能是必要的。例如,資料來源內有完整的地址,但您只想擷取其中的 City 及 PostalCode 屬性,那麼請將 Select 屬性設定為 new(City, PostalCode)。LinqDataSource 控制項會傳回一個 List<(Of <(T>)>) 集合,其中包含一個包括那些屬性之類別的執行個體。
若只選取一個屬性,則不必使用 new 功能,因為傳回的物件是該屬性之值的簡單集合。但選取多個屬性時,LinqDataSource 控制項必須建立新類別,以包含您指定的屬性。
用 Select 子句來計算值
您可以用 Select 子句來計算值。舉例來說,若要計算某訂單中項目行的總額,請將 Select 屬性設定為 new(SalesOrderDetailID, OrderQty * UnitPrice As LineItemTotal)。As 關鍵字可讓您指派名稱 (別名) 給計算出的值。如需詳細資訊,請參閱逐步解說:使用 LinqDataSource 和 GridView 控制項選取和篩選資料子集。
下列範例顯示如何使用 LinqDataSource 控制項來擷取資料子集。在範例中,Select 屬性設定為要指派別名給傳回的值,並計算出值。
<asp:LinqDataSource
ContextTypeName="ExampleDataContext"
TableName="OrderDetails"
Select="new(SalesOrderDetailID As DetailID,
OrderQty * UnitPrice As LineItemTotal,
DateCreated As SaleDate)"
ID="LinqDataSource1"
runat="server">
</asp:LinqDataSource>使用 Where 子句篩選資料
您可以篩選傳回的值,以便僅擷取出符合特定準則的記錄。您可以將 Where 屬性設定為一些條件,而記錄要符合這些條件才能包含在傳回的值中。如未指定 Where 屬性的值,則會擷取資料來源裡的所有記錄。您可以藉由建立篩選運算式來進行篩選,此運算式會利用比較來決定是否要包括某項記錄。它可以比較靜態值,也可以比較您用參數替代符號 (Placeholder) 指定的變數值。
用靜態值建立 Where 子句
當您將屬性中的值與靜態值比較時,會使用屬性及靜態值來定義 Where 屬性。舉例來說,如果只要傳回 ListPrice 值大於 1000 的記錄,請將 Where 屬性設定為 ListPrice > 1000。
您可以用 && 或 and 運算子做為邏輯 AND,用 || 或 or 運算子做為邏輯 OR。例如,將 Where 屬性設定為 ListPrice > 1000 || UnitCost > 500 || DaysToManufacture > 3,會傳回 ListPrice 值大於 1000 或 UnitCost 值大於 500,或 DaysToManufacture 值大於 3 的記錄。若指定必須符合所有條件才能傳回值,則要將 Where 屬性設定為 ListPrice > 1000 && UnitCost > 500 && DaysToManufacture > 3。
比較字串值時,條件必須以單引號括住,常值則必須以雙引號括住。例如,將 Where 屬性設定為 'Category = "Sports"',就會只擷取 Category 資料行等於 "Sports" 的記錄。
下列範例顯示 LinqDataSource 控制項,該控制項僅擷取以字串值及數值篩選後的資料。
<asp:LinqDataSource
ContextTypeName="ExampleDataContext"
TableName="Product"
Where='Category = "Sports" && Weight < 10'
ID="LinqDataSource1"
runat="server"
</asp:LinqDataSource>
建立參數型 Where 子句
如果要比較屬性值與只有在執行階段中才知道的值,請在 WhereParameters 屬性集合中定義參數。例如,您想用使用者提供的值來篩選資料,則您要建立一個參數來表示此值。LinqDataSource 控制項會用參數目前的值來建立 Where 子句。
下列範例顯示 LinqDataSource 控制項會根據使用者在名為 DropDownList1 之控制項中選取的值來擷取資料。
<asp:DropDownList AutoPostBack="true" ID="DropDownList1" runat="server">
<asp:ListItem Value="Sports">Sports</asp:ListItem>
<asp:ListItem Value="Garden">Garden</asp:ListItem>
<asp:ListItem Value="Auto">Auto</asp:ListItem>
</asp:DropDownList>
<asp:LinqDataSource
ContextTypeName="ExampleDataContext"
TableName="Products"
AutoGenerateWhereClause="true"
ID="LinqDataSource1"
runat="server">
<WhereParameters>
<asp:ControlParameter
Name="Category"
ControlID="DropDownList1"
Type="String" />
</WhereParameters>
</asp:LinqDataSource>
<asp:GridView
DataSourceID="LinqDataSource1"
ID="GridView1"
runat="server">
</asp:GridView>將 AutoGenerateWhereClause 屬性設定為 true 時,LinqDataSource 控制項就會自動建立 Where 子句。如果您有多個參數,這個選項會很好用,因為您不必在 Where 屬性中指定每一個條件,只要將各參數新增到 WhereParameters 屬性集合中,LinqDataSource 控制項就會建立一個包含每一個參數的 Where 子句。
將 AutoGenerateWhereClause 屬性設定為 true 時,參數名稱必須符合對應屬性的名稱。舉例來說,若要根據 Category 屬性來檢查參數值,參數必須命名為 Category。所有的比較都是相等比較,無法測試值是否大於或小於參數值。當您在 WhereParameters 集合中指定了一個以上的參數時,參數就會與邏輯 AND 連結。
如果要檢查不等比較或與邏輯 OR 的連結條件,可將 AutoGenerateWhereClause 屬性設定為 false。如此,您就可以定義 Where 屬性中的條件。請在每一個參數的 Where 屬性中包含一個替代符號。
下列範例顯示如何在篩選資料時測試不等比較。
<asp:DropDownList
AutoPostBack="true"
ID="DropDownList1"
runat="server">
<asp:ListItem Value="0">0</asp:ListItem>
<asp:ListItem Value="25">25</asp:ListItem>
<asp:ListItem Value="100">100</asp:ListItem>
<asp:ListItem Value="400">400</asp:ListItem>
</asp:DropDownList>
<asp:LinqDataSource
ContextTypeName="ExampleDataContext"
TableName="Products"
Where="Price > @UserPrice"
ID="LinqDataSource1"
runat="server">
<WhereParameters>
<asp:ControlParameter
Name="UserPrice"
DefaultValue="0"
ControlID="DropDownList1"
Type="Int32" />
</WhereParameters>
</asp:LinqDataSource>
<asp:GridView
DataSourceID="LinqDataSource1"
ID="GridView1"
runat="server">
</asp:GridView>如需詳細資訊,請參閱 AutoGenerateWhereClause。
資料分組與彙總
您可以將資料分組,把在一個或多個資料行中具有共同值的記錄資料進行合併彙算。您可以將 GroupBy 屬性設定為要用來合併彙算資料的屬性名稱。例如,資料表包含地址資訊,而您想依相同的城市值將記錄分組,則可將 GroupBy 設定為 City。
將 GroupBy 屬性與彙總功能一起使用,即可針對分組後的資料計算值,如某屬性的平均值或總和。您會透過參考 Key 物件來擷取要用於分組的值。
下列範例顯示如何將名為 ProductCategory 的屬性上之資料分組。將 Key 包含在 Select 屬性中,以擷取分組的值。Select 屬性中亦包括 Average 及 Count 彙總方法。
<asp:LinqDataSource
ContextTypeName="ExampleDataContext"
TableName="Products"
GroupBy="ProductCategory"
Select="new(Key,
Average(ListPrice) As AverageListPrice,
Average(Cost) As AverageCost,
Count() As RecordCount)"
ID="LinqDataSource1"
runat="server">
</asp:LinqDataSource>您可以使用 It 關鍵字來擷取屬於同一群組的個別記錄。如需詳細資訊,請參閱 HOW TO:使用 LinqDataSource 控制項分組和彙總資料。
彙總方法
下表列出當您使用 LinqDataSource 控制項時可用的彙總方法。
彙總函式 | 說明 |
|---|
Count() | 傳回一組資料的記錄總數。 |
Average(column) | 傳回所有傳回記錄中特定資料行的平均值。 |
Sum(column) | 傳回所有傳回記錄中特定資料行的總和值。 |
Max(column) | 傳回所有傳回記錄中特定資料行的最大值。 |
Min(column) | 傳回所有傳回記錄中特定資料行的最小值。 |
Where(condition) | 根據指定條件篩選傳回的記錄。 |
Any() | 判斷集合是否包含任何記錄。 |
All(condition) | 判斷集合中的所有記錄是否都符合指定條件。 |
更新、插入和刪除資料
排序資料
LinqDataSource 物件可以用兩種方式排序查詢中的資料。開發 Web 網頁時,您可以用靜態值排序資料。之後可以讓使用者在執行階段動態排序資料。
若要依靜態值排序資料,請將屬性名稱指派給 OrderBy 屬性。若要讓使用者在執行階段排序資料,請將 AutoSort 屬性設定為 true (預設值)。然後把排序運算式傳遞到 LinqDataSource 控制項。當資料繫結控制項的 AllowSorting 屬性設定為 true 時,資料繫結控制項 (如 GridView 控制項) 就會傳遞排序運算式。
若要在 OrderBy 屬性中指定一個以上的資料行名稱,請以逗號分隔各名稱。舉例來說,如果指定 "LastName, FirstName",則會先依 LastName 將記錄排序,記錄的 LastName 欄位中如果有相符值,再依 FirstName 來排序。
如果想先以特定順序傳回資料,再讓使用者變更順序,則可同時使用這兩種排序方法。此時請將 AutoSort 屬性設定為 true,並將 OrderBy 屬性設定為屬性名稱。
下列範例中的 LinqDataSource 控制項先依 LastName、再依 FirstName,然後再依 MiddleName 排序記錄。LinqDataSource 控制項也設定成可以讓使用者動態地排序資料列。您可以將資料控制項 (如 GridView 控制項) 繫結到 LinqDataSource 控制項來顯示資料,並讓使用者指定排列順序。
<asp:LinqDataSource
ContextTypeName="ExampleDataContext"
TableName="Contact"
OrderBy="LastName, FirstName, MiddleName"
AutoSort="true"
ID="LinqDataSource1"
runat="server"
</asp:LinqDataSource>
用參數來動態評估值
並行存取控制項
即使使用者可以更新或刪除資料,您也希望能在更新或刪除之前,先確保並沒有其他處理序已經變更了資料來源的資料。如果不檢查這些值是否已改變,則可能會不小心覆寫其他處理序設定的值,導致資料不一致。
LinqDataSource 控制項可以協助您判斷資料是否已改變。此控制項會將原始資料值以檢視狀態儲存在 Web 網頁中。Web 網頁張貼回來時,頁面會包含原始值及所有更新值。LinqDataSource 控制項會使用 LINQ to SQL 比較原始值跟目前位於資料來源的值。值如果相同,表示資料未變更,LINQ to SQL 就會更新或刪除資料。如果資料已變更,LINQ to SQL 會引發例外狀況。
您可以設定實體類別裡資料行的 UpdateCheck 屬性,來手動指定要檢查哪些資料行的值。O/R 設計工具在產生資料庫資料表的程式碼時,會將資料庫所管理資料行的 UpdateCheck 屬性設定為 Never。其他資料行的值則設定為 Always,表示該資料行永遠要進行並行存取檢查。將資料行的 UpdateCheck 屬性設定為 Never,可以避免將資料行納入並行存取檢查。此外,將屬性設定為 Never 還可避免該資料行的值以檢視狀態儲存。請只在使用者已變更該值時,才將 UpdateCheck 屬性設定為 WhenChanged 以便根據資料來源檢查值。
如果您必須以檢視狀態儲存敏感性資料,請加密檢視狀態。如需詳細資訊,請參閱在 ASP.NET 2.0 中加密 ViewState (英文)。
注意事項: |
|---|
加密檢視狀態可能會影響 Web 網頁的效能。 |
為 SQL Server 資料最佳化並行存取檢查
如果以檢視狀態儲存太多值,可能會使 Web 網頁過大,不小心讓使用者看到敏感性資訊。因此,使用 SQL Server 資料庫裡的資料時,可以在資料庫中建立一個內含時間戳記值的資料行,以提高 Web 網頁的效能與安全性。每次修改記錄時,SQL Server 都會自動更新時間戳記資料行。如此一來,LinqDataSource 控制項在判斷記錄是否變更時,就不必比較記錄中的每一個資料行,反之,您只要比較檢視狀態的時間戳記與資料庫中的時間戳記即可。
如果您在 SQL Server 資料庫中加入時間戳記資料行,O/R 設計工具就會自動建立實體類別,如此一來只有時間戳記會以檢視狀態儲存。如需詳細資訊,請參閱逐步解說:使用時間戳記搭配 LinqDataSource 控制項檢查資料完整性。
使用預存程序
若要使用 LinqDataSource 控制項從預存程序 (Stored Procedure) 中擷取資料,請為 Selecting 事件建立處理常式。在事件處理常式中,您會呼叫代表預存程序的資料內容類別方法。然後,將預存程序的結果設定為 LinqDataSourceSelectEventArgs 物件的 Result 屬性。如果您想要啟用自動更新、插入與刪除作業,則從方法傳回的型別必須符合 TableName 屬性中指定的型別。
下列範例示範如何將 Result 屬性指派給從方法 (表示預存程序) 傳回的物件。
Protected Sub LinqDataSource_Selecting(ByVal sender As Object, _
ByVal e As LinqDataSourceSelectEventArgs)
Dim exampleContext As ExampleDataContext = New ExampleDataContext()
e.Result = exampleContext.GetRegisteredCustomers()
End Sub
protected void LinqDataSource_Selecting(object sender,
LinqDataSourceSelectEventArgs e)
{
ExampleDataContext exampleContext = new ExampleDataContext();
e.Result = exampleContext.GetRegisteredCustomers();
}
如需建立資料內容方法的詳細資訊,請參閱 HOW TO:建立對應到預存程序和函式的 DataContext 方法 (O/R 設計工具)。
修改資料時驗證值
LinqDataSource 控制項事件