ここで、お小遣いService.csの中身を軽く見ておきましょう。
リスト1は、自動生成されたコードからコメントを取り除いたものです。
図13でドメインサービスを作成したときに、お小遣い明細、お小遣い分類に対する検索処理、お小遣い明細に対する追加/更新/削除の処理が、指定通りにドメインサービスに追加されていることが確認できます。
ここでは、日付のFrom/Toから明細を検索する「Findお小遣い明細ByDate」メソッドを、新たに追加しています。
注意が必要なのは、WCF RIA Serviceで公開するメソッドはオーバーロード(引数が違う同名のメソッドを定義)することはできない点です。例えば、お小遣い帳のデータをすべて取得する「IQueryable Getお小遣い明細()」メソッドと、検索条件を指定して取得する「IQueryable Getお小遣い帳(DateTime, DateTime)」は、同時に1つのサービスに設定できません。この場合は、値を取得するメソッドを「Find~~ByDate」のように、別名でメソッドを追加する必要があります。
namespace RIAServicesSample.Web
{
using System;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Hosting;
[EnableClientAccess()]
public class お小遣いService : LinqToEntitiesDomainService<お小遣いEntities> {
public IQueryable<お小遣い分類> Getお小遣い分類()
{
return this.ObjectContext.お小遣い分類;
}
public IQueryable<お小遣い明細> Getお小遣い明細()
{
return this.ObjectContext.お小遣い明細;
}
// 新たに手動で追加した検索メソッド
public IQueryable<お小遣い明細> Findお小遣い明細ByDate(DateTime from, DateTime to)
{
return this.ObjectContext.お小遣い明細.Where(明細 => from <= 明細.日付 && 明細.日付 >= to);
}
public void Insertお小遣い明細(お小遣い明細 お小遣い明細)
{
if ((お小遣い明細.EntityState != EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(お小遣い明細, EntityState.Added);
}
else
{
this.ObjectContext.お小遣い明細.AddObject(お小遣い明細);
}
}
public void Updateお小遣い明細(お小遣い明細 currentお小遣い明細)
{
this.ObjectContext.お小遣い明細.AttachAsModified(currentお小遣い明細, this.ChangeSet.GetOriginal(currentお小遣い明細));
}
public void Deleteお小遣い明細(お小遣い明細 お小遣い明細)
{
if ((お小遣い明細.EntityState == EntityState.Detached))
{
this.ObjectContext.お小遣い明細.Attach(お小遣い明細);
}
this.ObjectContext.お小遣い明細.DeleteObject(お小遣い明細);
}
}
}
以上で、サーバ側のサービスの準備は終わりです。
データの表示
サーバ側のドメインサービスが用意できたので、Silverlightでデータを取得してDataGridに一覧表示してみましょう。Silverlight側のプロジェクトのMainPage.xamlを開き、データソースウインドウからお小遣い明細をページにドロップします(図14)。

図14で自動生成されたXAMLに対して、リストに表示する必要のない最終更新日などのプロパティを除き、レイアウトを修正したコードがリスト2です。
検索フィールドに配置されたLoadボタンは、「お小遣い明細DomainDataSource」クラスのLoadCommandメソッドにバインドされています。
<UserControl x:Class="RIAServicesSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"
xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
xmlns:my="clr-namespace:RIAServicesSample.Web"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
<StackPanel x:Name="LayoutRoot" Background="White">
<!-- データソースの定義 -->
<riaControls:DomainDataSource
AutoLoad="False"
d:DesignData="{d:DesignInstance my:お小遣い明細, CreateList=true}"
LoadedData="お小遣い明細DomainDataSource_LoadedData"
Name="お小遣い明細DomainDataSource"
QueryName="Findお小遣い明細ByDateQuery">
<riaControls:DomainDataSource.DomainContext>
<my:お小遣いContext />
</riaControls:DomainDataSource.DomainContext>
<riaControls:DomainDataSource.QueryParameters>
<riaControls:Parameter ParameterName="from" Value="{Binding ElementName=fromTextBox, Path=Text}" />
<riaControls:Parameter ParameterName="to" Value="{Binding ElementName=toTextBox, Path=Text}" />
</riaControls:DomainDataSource.QueryParameters>
</riaControls:DomainDataSource>
<!-- 検索フィールド -->
<StackPanel Orientation="Horizontal" >
<sdk:Label Content="From:" VerticalAlignment="Center" />
<sdk:DatePicker Name="fromTextBox" Width="120" />
<sdk:Label Content="To:" VerticalAlignment="Center" />
<sdk:DatePicker Name="toTextBox" Width="120" />
<Button Command="{Binding Path=LoadCommand, ElementName=お小遣い明細DomainDataSource}" Content="検索" Name="お小遣い明細DomainDataSourceLoadButton" />
</StackPanel>
<!-- データグリッド -->
<sdk:DataGrid AutoGenerateColumns="False"
Height="200" Width="400" HorizontalAlignment="Left"
ItemsSource="{Binding ElementName=お小遣い明細DomainDataSource, Path=Data}"
Name="お小遣い明細DataGrid"
RowDetailsVisibilityMode="VisibleWhenSelected" VerticalAlignment="Top">
<sdk:DataGrid.Columns>
<sdk:DataGridTemplateColumn Header="日付" Width="SizeToHeader">
<sdk:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<sdk:DatePicker SelectedDate="{Binding Path=日付, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellEditingTemplate>
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=日付, StringFormat=\{0:d\}}" />
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
<sdk:DataGridTextColumn Binding="{Binding Path=連番}" Header="連番" Width="SizeToHeader" />
<sdk:DataGridTextColumn Binding="{Binding Path=お小遣い分類Id}" Header="お小遣い分類" Width="SizeToHeader" />
<sdk:DataGridTextColumn Binding="{Binding Path=タイトル}" Header="タイトル" Width="SizeToHeader" />
<sdk:DataGridTextColumn Binding="{Binding Path=金額}" Header="金額" Width="SizeToHeader" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</StackPanel>
</UserControl>
ここまでで、サーバからデータを取得する設定が完了しました。早速、デバッグを実行してみましょう。検索の開始日と終了日を入力し、Loadボタンをクリックすると、結果が表示されます(図15)。クライアント側は、定義されたオブジェクトを単純に画面にドロップしただけで、検索画面が作成できます。

通常、SilverlightからWCFのサービスを呼び出すときには、WCFのサービス参照を作成し、Webサービスを非同期で呼び出す必要があります。しかし、WCF RIA Servicesのプロジェクトには、サービス参照は追加されておらず、Webサービスの呼び出しコードも存在しません。
これらの仕事を請け負っているのが自動生成コードです。Visual StudioのソリューションエクスプローラでSilverlightプロジェクトのすべてのファイルを表示してみましょう。

Generated_Codeフォルダの下に、コードファイルがあるのを確認できます。
実は、この自動生成されたコードファイルの中で、Webサービスの呼び出し、値の検証、エンティティーの宣言などが行われているのです。自動生成コードや値の検証については後編で詳しく取り上げます。
