逐步解說:加入查詢方法
本逐步解說將說明如何在 WCF RIA Services 中加入及自訂可查詢資料來源的方法。這種方法稱為查詢方法,必須以簽章定義,當架構指定查詢方法時會以簽章來做識別。只要查詢方法套用 QueryAttribute 即會滿足這項需求。預期的查詢簽章集合大致上可以分成兩大分類:查詢永遠傳回 Entity 的單一型別,以及查詢可能傳回 IEnumerable 或 IQueryable 中 T 型別的多個 Entity。如需允許的查詢方法簽章的詳細資訊,請參閱網域服務。
當您在 [加入新的 DomainService 類別] 對話方塊中建立新的 DomainService 類別並指定其實體時,RIA Services 架構會在這個類別中為每個由服務公開的實體,自動建立簡單查詢方法。此查詢方法只擷取實體的所有記錄。本逐步解說將說明如何加入新的查詢方法,執行更複雜的案例,例如依參數值進行篩選。本逐步解說將示範如何加入可傳回單一實體的查詢,以及加入可傳回實體集合的查詢。
必要條件
除了 WCF RIA Services 和 WCF RIA Services 工具組之外,在 RIA Services 文件中呈現的這個逐步解說和其他逐步解說還需要正確安裝並設定數個必要程式 (例如 Visual Studio 2010 和 Silverlight 開發人員執行階段與 SDK)。要執行逐步解說還需要安裝並設定 SQL Server 2008 R2 Express with Advanced Services,以及安裝 AdventureWorks OLTP 和 LT 資料庫。
在 WCF RIA Services 的必要條件節點中的主題也提供符合這些必要條件的詳細指示。請先按照該處提供的指示進行,然後再進行本逐步解說,以確保您在進行本 RIA Services 逐步解說時不會發生問題。
本逐步解說假設您已完成逐步解說:建立 RIA Services 方案所述之程序,而且已在那裡完成可從這裡所述之程序進行修改的方案。
若要加入一個可接受參數且傳回單一實體的查詢方法
開啟逐步解說:建立 RIA Services 方案主題中建構的方案,這個方案會公開 Customer 資料表的資料。
在伺服器專案中,開啟公開 Customer 資料表資料的
CustomerDomainService
DomainService 類別。加入一個可接受整數參數且傳回符合客戶 ID 之
Customer
實體的查詢方法。如果可傳回單一實體的方法包含 QueryAttribute 屬性 (Attribute),您必須將 IsComposable 屬性 (Property) 設為 false。使用者無法從用戶端指定其他的查詢作業。如果查詢方法符合預期的查詢簽章,就不必套用 QueryAttribute 屬性。傳回值必須是實體物件的單一執行個體。
<Query(IsComposable:=False)> Public Function GetCustomersByID(ByVal customerID As Integer) As Customer Return Me.ObjectContext.Customers.SingleOrDefault(Function(c) c.CustomerID = customerID) End Function
[Query(IsComposable=false)] public Customer GetCustomersByID(int customerID) { return this.ObjectContext.Customers.SingleOrDefault(c => c.CustomerID == customerID); }
若要加入一個可接受參數且傳回實體集合的查詢方法
開啟公開 Customer 資料表資料的 DomainService 類別。
在
CustomerDomainService
DomainService 類別中加入一個可接受字串參數且傳回姓氏開頭為該字母之客戶的查詢方法。這個方法會傳回 IQueryable 物件,因為使用者可能要從用戶端提供其他查詢作業。
Public Function GetCustomersByLastNameLetter(ByVal startingLastNameLetter As String) As IQueryable(Of Customer) Return Me.ObjectContext.Customers.Where(Function(c) c.LastName.StartsWith(startingLastNameLetter) = True) End Function
public IQueryable<Customer> GetCustomersByLastNameLetter(string startingLastNameLetter) { return this.ObjectContext.Customers.Where(c => c.LastName.StartsWith(startingLastNameLetter) == true); }
若要在用戶端專案中顯示那些查詢方法的結果
在用戶端專案中,開啟 MainPage.xaml。
加入兩個 TextBox 控制項和兩個 Button 控制項,讓使用者依 ID 或姓氏的第一個字母篩選客戶記錄。
下列 XAML 顯示完整的配置以及現有的 DataGrid。
<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="RIAServicesExample.MainPage" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <Grid x:Name="LayoutRoot" Background="White"> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="25"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="0"> <TextBlock Text="search by id: " ></TextBlock> <TextBox Name="IDValue" Width="50" ></TextBox> <Button Name="IDButton" Click="IDButton_Click" Content="Submit"></Button> </StackPanel> <StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="1"> <TextBlock Text="search by name: "></TextBlock> <TextBox Name="LetterValue" Width="30"></TextBox> <Button Name="LetterButton" Click="LetterButton_Click" Content="Submit"></Button> </StackPanel> <data:DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Name="CustomerGrid"></data:DataGrid> </Grid> </UserControl>
開啟 MainPage.xaml 的程式碼後置檔案 (MainPage.xaml.cs 或 MainPage.xaml.vb)。
加入程式碼來根據使用者輸入擷取查詢結果。
Imports RIAServicesExample.Web Imports System.ServiceModel.DomainServices.Client Partial Public Class MainPage Inherits UserControl Dim _customerContext As New CustomerDomainContext Public Sub New() InitializeComponent() End Sub Private Sub LetterButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) IDButton.IsEnabled = False LetterButton.IsEnabled = False Dim loadOp = Me._customerContext.Load(Me._customerContext.GetCustomersByLastNameLetterQuery(LetterValue.Text), AddressOf CustomerLoadedCallback, Nothing) CustomerGrid.ItemsSource = loadOp.Entities End Sub Private Sub IDButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) IDButton.IsEnabled = False LetterButton.IsEnabled = False Dim loadOp = Me._customerContext.Load(Me._customerContext.GetCustomersByIDQuery(IDValue.Text), AddressOf CustomerLoadedCallback, Nothing) CustomerGrid.ItemsSource = loadOp.Entities End Sub Public Sub CustomerLoadedCallback(ByVal loadOperation As LoadOperation(Of Customer)) IDButton.IsEnabled = True LetterButton.IsEnabled = True End Sub End Class
using System; using System.Windows; using System.Windows.Controls; using RIAServicesExample.Web; using System.ServiceModel.DomainServices.Client; namespace RIAServicesExample { public partial class MainPage : UserControl { private CustomerDomainContext _customerContext = new CustomerDomainContext(); public MainPage() { InitializeComponent(); } private void LetterButton_Click(object sender, RoutedEventArgs e) { IDButton.IsEnabled = false; LetterButton.IsEnabled = false; LoadOperation<Customer> loadOp = this._customerContext.Load(this._customerContext.GetCustomersByLastNameLetterQuery(LetterValue.Text), CustomerLoadedCallback, null); CustomerGrid.ItemsSource = loadOp.Entities; } private void IDButton_Click(object sender, RoutedEventArgs e) { IDButton.IsEnabled = false; LetterButton.IsEnabled = false; LoadOperation<Customer> loadOp = this._customerContext.Load(this._customerContext.GetCustomersByIDQuery(int.Parse(IDValue.Text)), CustomerLoadedCallback, null); CustomerGrid.ItemsSource = loadOp.Entities; } void CustomerLoadedCallback(LoadOperation<Customer> loadOperation) { IDButton.IsEnabled = true; LetterButton.IsEnabled = true; } } }
執行 (F5) 應用程式。
下圖顯示當應用程式執行時出現的一份依姓氏篩選的客戶清單。