normalian blog

Let's talk about Microsoft Azure, ASP.NET and Java!

RIA Servicesでテーブル・ストレージを利用する その2 〜ローカル実行で追加処理編〜

id:waritohutsu:20101103:1288751665 の記事で、Windows Azureストレージ・サービスでSilverilght RIA Servicesの利用方法を紹介した。当該記事では、Silverlightプロジェクトには参照処理のみ実装したが、テーブル・ストレージにエンティティが一つも格納されていないため、Silverlight側で何も表示されなかった。
そこで今回は、ローカル環境(Development Fabric、Development Storage)でデータの参照&追加を実施するまでの手順を紹介する。

Azure Storage Explorer でのエンティティ追加

まず、Azure Storage Explorer を利用して以下のエンティティをCommentEntityテーブルに追加したが、なぜかSilverlight側のDataGridでは何も表示されなかった。

プロパティ名
PartitionKey aaaa
RowKey bbbb
TimeStamp 空(自動付与)
Name aaaa
Body bbbb

Silverlight側にエンティティ追加機能を実装

ならばエンティティを追加する処理を実装するしかないので、どっとねっとふぁんBlog > WCF RIA Services:データ追加 を参考にして、以下の実装を行った。

  1. ChildWindow1.xaml の作成
  2. ChildWindow1.xaml.cs の修正
  3. MainPage.xaml の修正
  4. MainPage.xaml.cs の修正
1. ChildWindow1.xaml の作成

新規エンティティの編集を行う子ウィンドウを作成する。Silverlightプロジェクトを右クリックして[追加(D)]-[新しい項目(W)]を選択し、「Silverlight 子ウィンドウ」を選択する。

作成した ChildWindow1.xaml に対して、[データソース]ウィンドウから CommentEntity を[詳細]にして、子ウィンドウにドラッグ&ドロップする。

次に、以下の例に従ってcommentEntityDomainDataSourceのAutoLoadプロパティをfalseする。

  • ChildWindow1.xaml の抜粋
<riaControls:DomainDataSource AutoLoad="False" 
    d:DesignData="{d:DesignInstance my1:CommentEntity, CreateList=true}" Height="0"
    LoadedData="commentEntityDomainDataSource_LoadedData"
    Name="commentEntityDomainDataSource" QueryName="GetCommentEntitiesQuery" Width="0">
    <riaControls:DomainDataSource.DomainContext>
        <my:CommentDomainContext />
    </riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>
2. ChildWindow1.xaml.cs の修正

修正したコードを以下に記載する。修正箇所はコメントで記述したので参考にして頂きたい。

namespace SilverlightApplication1
{
    using WebRole1;
    using WebRole1.Model;

    public partial class ChildWindow1 : ChildWindow
    {
        CommentEntity comment = null;

        public ChildWindow1()
        {
            InitializeComponent();


            // 新規エンティティの作成/追加と入力欄への関連づけ 
            comment = new CommentEntity();
            ((CommentDomainContext)commentEntityDomainDataSource.DomainContext)
                .CommentEntities.Add(comment);
            grid1.DataContext = comment;
        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            // エンティティの検証および追加 
            commentEntityDomainDataSource.SubmitChanges();
            if (comment.HasValidationErrors == false)
                this.DialogResult = true;
        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = false;
        }

        private void commentEntityDomainDataSource_LoadedData(object sender, LoadedDataEventArgs e)
        {

            if (e.HasError)
            {
                System.Windows.MessageBox.Show(e.Error.ToString(), "Load Error", System.Windows.MessageBoxButton.OK);
                e.MarkErrorAsHandled();
            }
        }
    }
}
3. MainPage.xaml の修正

親ウィンドウに[追加]ボタンを作成する(下図を参照)。

次に、[追加]ボタンの[Click]イベントにイベントハンドラを追加し、MainPage.xaml.cs側で処理を記述する。

4. MainPage.xaml.cs の修正

作成した[追加]ボタンの[Click]イベントにて、ChildWindow1を呼び出す処理を記述する。以下に作成したサンプルを記述するので、参考にして頂きたい。

namespace SilverlightApplication1
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            // 子ウィンドウのインスタンスを生成
            ChildWindow1 w = new ChildWindow1();
            // 子ウィンドウを閉じたときにデータを読み直す処理を実装
            w.Closed += (s, ev) =>
            {
                if (w.DialogResult == true)
                {
                    commentEntityDomainDataSource.Load();
                }
            };
            // 子ウィンドウの表示
            w.Show(); 
        }
    }
}

修正したサンプルアプリケーションの実行

サンプルアプリケーションを実行したところ、以下の通り無事エンティティの参照処理と追加処理が実行できた(左:MainPage.xaml、左:ChildWindow1.xaml)。

考察

  • エンティティ追加時にDataGridが更新されない問題

本処理では、エンティティ追加時に一つ前の画面が表示されてしまうという問題がある。どっとねっとふぁんBlog > WCF RIA Services:データ追加の補足 を参考に、「commentEntityDomainDataSource.Load()」が非同期に呼び出されることを考慮した実装も試みたが、現時点ではうまくいかず(汗。

  • Azure Storage Exploreで追加したエンティティが表示されない問題

作成したサンプルアプリケーションでエンティティ追加後、Azure Storage ExploreでCommentEntityテーブルの中身を参照した。

画像からご理解いただけると思うが、PartitionKeyにドメインサービス名、RowKeyにはGuidが割り当てられているように見受けられる。そこで、ParitionKeyをドメインサービス名とした以下のエンティティを追加した。

当該エンティティ追加後、再度CommentEntityテーブルのエンティティを読み込んだところ、以下の結果となった。

どうやら、デフォルトでは、テーブル・ストレージ向けRIA Services は自身のドメインサービス名をParitionKeyの値としたエンティティのみを読み取りに行く?ようだ。