チュートリアル: クエリ メソッドの追加
このチュートリアルでは、WCF RIA サービス でデータ ソースを照会するメソッドを追加およびカスタマイズする方法について説明します。このようなメソッドは、クエリ メソッドと呼ばれており、クエリ メソッドを指定する際にフレームワークによって認識されるシグネチャを使用して定義する必要があります。クエリ メソッドでこの要件を満たすには、QueryAttribute を適用します。予想される一連のクエリ シグネチャは大きく 2 つに分けられます。1 つは、常に単一の種類の Entity を返すクエリ、もう 1 つは、IEnumerable または IQueryable で T 型の複数の Entity を返す可能性のあるクエリです。使用できるクエリ メソッド シグネチャの詳細については、「ドメイン サービス」を参照してください。
[新しいドメイン サービス クラスの追加] ダイアログ ボックスで新しいドメイン サービス クラスを作成してエンティティを指定すると、RIA サービス フレームワークによって、サービスが公開する各エンティティのこのクラスに単純なクエリ メソッドが自動的に作成されます。このクエリ メソッドは、エンティティのすべてのレコードを取得するだけです。このチュートリアルでは、パラメーター値によるフィルター処理など、より複雑なシナリオを実行する新しいクエリ メソッドを追加する方法について説明します。また、1 つのエンティティを返すクエリを追加する方法に加え、エンティティのコレクションを返すクエリを追加する方法についても説明します。
前提条件
このチュートリアル、および RIA サービス のドキュメントで紹介されている他のチュートリアルでは、WCF RIA サービス および WCF RIA サービス Toolkit に加え、Visual Studio 2010 や Silverlight の開発者向けランタイムと SDK など、前提条件となっているいくつかのプログラムが適切にインストールおよび構成されている必要があります。また、SQL Server 2008 R2 Express with Advanced Services をインストールして構成し、AdventureWorks OLTP と LT データベースをインストールすることも必要です。
これらの各前提条件を満たしているかどうかを確認するための詳細な手順については、「WCF RIA Services の前提条件」ノード内のトピックを参照してください。このチュートリアルを進める前に、トピックに記載されている手順に従って、この RIA サービス チュートリアルを実行するときに発生する問題をできるだけ最小限に抑えるようにします。
このチュートリアルでは、「チュートリアル: RIA Services ソリューションの作成」に記載されている手順を完了していること、およびその手順で作成したソリューションをここに記載されている手順で変更できるように準備できていることを前提としています。
パラメーターを受け取り 1 つのエンティティを返すクエリ メソッドを追加するには
「チュートリアル: RIA Services ソリューションの作成」で構築した、Customer テーブルのデータを公開するソリューションを開きます。
サーバー プロジェクトで、Customer テーブルのデータを公開する
CustomerDomainService
ドメイン サービス クラスを開きます。整数パラメーターを受け取って
Customer
エンティティと対応する顧客 ID を返すクエリ メソッドを追加します。1 つのエンティティを返すメソッドに QueryAttribute 属性が含まれている場合は、IsComposable プロパティを false に設定する必要があります。ユーザーはクライアントから追加のクエリ操作を指定することはできません。クエリ メソッドがクエリの予想されるシグネチャと一致する場合、QueryAttribute 属性を適用する必要はありません。戻り値は、エンティティ オブジェクトの 1 つのインスタンスである必要があります。
<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 テーブルのデータを公開するドメイン サービス クラスを開きます。
CustomerDomainService
ドメイン サービス クラスで、文字列パラメーターを受け取り、姓がその文字で始まるすべての顧客を返すクエリ メソッドを追加します。ユーザーはクライアントから追加のクエリ操作を指定できるため、このメソッドは 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 を開きます。
2 つの TextBox コントロールと 2 つの 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 キーを押します)。
次の図は、アプリケーションの実行時に表示される、姓でフィルター処理された顧客の一覧を示しています。