ページ

2012年11月13日火曜日

◆Visual Studio 2012 で Silverlight RIA Service を試してみる2

以下のチュートリアルを順を追って試してみる。
http://msdn.microsoft.com/ja-jp/library/ee707376(v=vs.91).aspx

サンプルデータベースは必ずしもチュートリアルと同じものを使わなくても試せると思うが、AdventureWorksを使うのならば以下からダウンロードできる。(AdventureWorksLTが小さくて良いかもしれない)
Microsoft SQL Server Product Samples: Database - Download: SQL Server 2005 SP2a

定番のNorthwndあたりでも良さそうに思う。

<プロジェクト間にRIA Services リンクを使用したソリューションの作成>

RIA Service ソリューションを設定するには

  1. 新しいプロジェクトをクリック
    image
  2. [インストールされたテンプレート] の [Silverlight] で [Silverlight アプリケーション] テンプレートをクリックし、新しいプロジェクトにRIAServicesExample という名前を付けて「OK」をクリック
    image
  3. 表示された「新しいSilverlightアプリケーション」ダイアログで、「WCF RIA サービスを有効にする」をチェックして「OK」ボタンをクリックする
    image

 

<データモデルの作成>

予め「AdventureWorksLT」への接続が作成してある前提とする

データを中間層で使用できるようにするには

  1. ソリューション エクスプローラーで、サーバー プロジェクト RIAServicesExample.Web を右クリックし、[追加] をポイントして、[新しい項目] をクリック
  2. 左ペインで「データ」カテゴリを選び、「ADO.NET Entity Data Model」をクリックする
  3. 「名前」欄に「AdventureWorksModel」という名前をつけて「追加ボタン」をクリックする
    image
  4. 「Entity Data Model ウィザード」にて「データベースから生成」を選択して「次へ」ボタンをクリック
    image
  5. 「Entity Data Model ウィザード」画面にて、予め作成済みの「AdventureWorks」への接続を指定して「次へ」ボタンをクリック
  6. 「データベースオブジェクトと設定の選択」画面にて「Address」「Customer」「CustomerAddress」のテーブルをチェックして「完了」ボタンをクリック
  7. ソリューションエクスプローラにて「AdventureWorksModel.edmx」配下の「*.tt」ファイルを削除
    image
  8. edmxダイアグラムの空白部分をクリックして「AdventureWorksLTModel」のプロパティを表示させ、「コード生成方法」に「規定」を指定する
    image
  9. 「F6」キーを押して一旦ビルド

<ドメインサービスの作成>

ドメインサービスを作成するには

  1. ソリューション エクスプローラーにて「RIAServicesExample.Web」プロジェクトを右クリックし「追加」「新しい項目」をクリック
  2. カテゴリの一覧で「Web」を選択し、「DomainServiceクラス」テンプレートをクリック
  3. クラスに「CustomerDomainService」という名前を付ける
  4. 「追加」ボタンをクリック
  5. 「新しいドメインサービスクラスの追加」ダイアログが表示されるので「Customer」エンティティを選択し、編集の有効化をチェックし、「OK」ボタンをクリック
    image

<Silverlightクライアントの作成>

データを表示するには

  1. 「RIAServicesExample」プロジェクトの「MainPage.xaml」を開く

  2. ツールボックスからXAMLビューのGrid要素内に「DataGridコントロール」をドラッグする

  3. 名前を「CustomerGrid」とする

       1: <Grid x:Name="LayoutRoot" Background="White">
       2:     <sdk:DataGrid x:Name="CustomerGrid"/>
       3: </Grid>


  4. 「F7」キーを押してコードビハインドを表示させ、ネームスペースに次の2つのステートメントを追加する(using RIAServicesExample.Web; および using System.ServiceModel.DomainServices.Client;)



  5. 「GetCustomerQuery」メソッドを呼び出してデータを取得し、「CustomerGrid」にバインドする


       1: public partial class MainPage : UserControl
       2: {
       3:     CustomerDomainContext _customerContext = new CustomerDomainContext();
       4:  
       5:     public MainPage()
       6:     {
       7:         InitializeComponent();
       8:  
       9:         LoadOperation<Customer> loadOp = this._customerContext.Load(_customerContext.GetCustomersQuery());
      10:         CustomerGrid.ItemsSource = loadOp.Entities;
      11:     }
      12: }


  6. 「F5」キーを押して実行し「Customer」テーブルの内容が表示されるのを確認する
    image

<クライアントでのクエリのカスタマイズ>


「CustomerID」が20以下のデータのみを表示する



  1. 「RIAServicesExample」プロジェクトで「MainPage.xaml.cs」を開く

  2. コンストラクタメソッドを以下のように修正する


    public MainPage()
    {
        InitializeComponent();
     
        var query = this._customerContext.GetCustomersQuery().Where(c => c.CustomerID <= 20);
        LoadOperation<Customer> loadOp = this._customerContext.Load(query);
        //LoadOperation<Customer> loadOp = this._customerContext.Load(_customerContext.GetCustomersQuery());
        CustomerGrid.ItemsSource = loadOp.Entities;
    }

  3. 「F5」キーを押して実行し、「CustomerID」が20以下のデータが表示されるのを確認する
    image

(確認できたらすべてのCustomerIDを表示するよう、元に戻しておく)


<サーバーでのクエリのカスタマイズ>


パラメータを受け取り単一の結果(エンティティ)を返すクエリを追加する



  1. 「RIAServicesExample.Web」プロジェクトの「CustomerDomainService.cs」を開き以下のクエリーを追加する。(CustomerIDを指定して1件抽出するクエリー)

    public Customer GetCustomerByID(int customerID)
    {
        return this.ObjectContext.Customers.SingleOrDefault(c => c.CustomerID == customerID);
    }

    なお、MSのチュートリアルではこのメソッドに「Query」属性を指定しているが基本的には要らないようだ。(Customerとかのエンティティではない型を返す場合には必要になるのかもしれない)

パラメータを受け取りエンティティのコレクションを返すクエリを追加する



  1. 「RIAServicesExample.Web」プロジェクトの「CustomerDomainService」を開き以下のクエリーを追加する。(LastNameの開始文字を指定して複数件抽出するクエリー)

    public IQueryable<Customer> GetCustomersByLastNameLetter(string startingLastNameLetter)
    {
        return this.ObjectContext.Customers.
            Where(c => c.LastName.StartsWith(startingLastNameLetter) == true);
    }

 


クエリ結果を表示する



  1. 「RIAServicesExample」プロジェクトで「MainPage.xaml」を開き抽出条件を指定するためにXAMLを修正する。

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition />
        </Grid.RowDefinitions>
        
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="IDで検索:" />
            <TextBox x:Name="idParam" Width="50"/>
            <Button x:Name="btnID" Content="実行" Click="btnID_Click" />
        </StackPanel>
        <StackPanel Grid.Column="1" Orientation="Horizontal">
            <TextBlock Text="名前で検索:" />
            <TextBox x:Name="nameParam" Width="50"/>
            <Button x:Name="btnName" Content="実行" Click="btnName_Click" />
        </StackPanel>
        <sdk:DataGrid x:Name="CustomerGrid" Grid.Row="1" Grid.ColumnSpan="2"/>
    </Grid>

    image

  2. コードビハインドを開き「実行」ボタンのイベントハンドラーを以下のように指定する。

    private void btnID_Click(object sender, RoutedEventArgs e)
    {
        btnID.IsEnabled = false;
        btnName.IsEnabled = false;
        LoadOperation<Customer> loadOp = this._customerContext.Load(this._customerContext.
            GetCustomerByIDQuery(int.Parse(idParam.Text)), CustomerLoadedCallBack, null);
        CustomerGrid.ItemsSource = loadOp.Entities;
    }
    private void btnName_Click(object sender, RoutedEventArgs e)
    {
        btnID.IsEnabled = false;
        btnName.IsEnabled = false;
        LoadOperation<Customer> loadOp = this._customerContext.Load(this._customerContext.
            GetCustomersByLastNameLetterQuery(nameParam.Text), CustomerLoadedCallBack, null);
        CustomerGrid.ItemsSource = loadOp.Entities;
    }
     
    private void CustomerLoadedCallBack(LoadOperation<Customer> obj)
    {
        btnID.IsEnabled = true;
        btnName.IsEnabled = true;
    }

  3. 「F5」キーを押して実行し、「CustomerID」での抽出、「LastName」での抽出を試してみる。
    image

<InvokeOperationを使ってドメインサービスを呼び出す


ドメインサービスを呼び出すにはこれまで使用した「LoadOperation」以外に「InvokeOperation」というクラスが存在する。


今のところ、サンプルや資料を見た限りその違いは今一つ良く判らない。(今後使っていくと判るのかもしれない)
さしあたって、エンティティではなくプリミティブなデータ型を取得する場合に使用するのかも?ってところ。


呼び出し操作を追加するには



  1. 「RIAServicesExample.Web」プロジェクトで「CustomerDomainService.cs」を開く
  2. 以下のメソッドを追加する


     public DateTime GetToday()
     {
         return DateTime.Today;
     }

  3. 「F6」キーを押して一旦ビルド
  4. 「RIAServicesExample」クライアントプロジェクトで「MainPage.xaml」を開く
  5. 「Grid」に1行追加


     <Grid x:Name="LayoutRoot" Background="White">
         <Grid.ColumnDefinitions>
             <ColumnDefinition />
             <ColumnDefinition />
         </Grid.ColumnDefinitions>
         <Grid.RowDefinitions>
             <RowDefinition Height="30"/>
             <RowDefinition />
             <RowDefinition Height="30"/>
        </Grid.RowDefinitions>

  6. 「DataGrid」の下にサービス呼び出し用のボタンと結果表示用の「TextBlock」を追加


      <sdk:DataGrid x:Name="CustomerGrid" Grid.Row="1" Grid.ColumnSpan="2"/>
      <StackPanel Grid.Row="2" Orientation="Horizontal">
          <Button x:Name="btnGetToday" Content="GetToday" Click="btnGetToday_Click"/>
          <TextBlock x:Name="txtToday" Width="100" />
      </StackPanel>

  7. 「MainPage.xaml.cs」を開きボタンのイベントハンドラーに以下の処理を追加する


      private void btnGetToday_Click(object sender, RoutedEventArgs e)
      {
          InvokeOperation<DateTime> invokeOp = this._customerContext.GetToday((op) =>
              {
                  if (op.HasError)
                  {
                      MessageBox.Show("Error");
                      return;
                  }
                  else
                  {
                      txtToday.Text = op.Value.ToString("yyyy年MM月dd日");
                  }
              }, null);
      }


  8. 「F5」キーを押して実行し、「GetToday」ボタンをクリックして今日の日付が表示されるのを確認する
    image

0 件のコメント:

コメントを投稿

私が最近チェックした記事