Silverlight WCF RIA Service を今更ながらおさらいする。
Mix11 も終わりました。
予定通りSilverlight5 Betaの発表も予定通り行われましたが、予定通り、びっくりするような機能は発表されませんでしたね・・・。ま、Silverlightそのものより、今後は、Windows phone7 のUI技術として発展するんですかね。
ま、未来の問題はさておき、現実的な課題についての話題。
周知の事実ですが、Silverlight からダイレクトにDBに接続することは原則としてできません。
これはSilverlight がしょぼいからではなく、セキュリティー上の問題というか、コンセプトの問題からです。
そのため、DBにアクセスしたい場合などには、一度、DBをWCFでラップし、それを経由してアクセスすることになるのですが、これが、何かと面倒なのは言うまでもありません。
それを(見た目上)解決するのがSilverlight WCF RIA Services です。
Silverligh3時代からオプションで登場し、Silverlight4で標準となり、Silverlight5 では特に変化がない感じですかね・・・。
このWCF RIA Services を利用すれば(裏でこっそりWCFが作成され、かつ、それを利用するプロキシクラスが生成されるので)、あたかもローカルクラスを利用するようにDB等のデータソースをハンドリングすることができます。
このWCF RIA Services ですが、ドラッグアンドドロップでグリッドを作るデモは多くあるのですが、普通のコーディングでクラスを操作する方法はあまりないので、そっちのやり方をメモしておきます。
話はそれますが、Silverlight はやたらXAML ベースの情報が多いのですが、XAML 記述でまともなアプリを完成させることははまず不可能なため、もっとC#でSilverlightを制御する方法をMSさんには充実させてほしいなあ・・・と思うのは私だけでしょうか。
愚痴はさておき、WCF RIA Services の利用方法。
WCF RIA Services の利用の流れは、、、
- VSを起動してプロジェクトの基本的な設定
- データソースを定義(DB)
- データソースに対するDomain Service (DBにアクセスするクラス)を定義
- Domain Service を介してDBにアクセス
の4段階になります。
1.VSを起動してプロジェクトの基本的な設定
まず、VSを起動し、Silverlight Application を選びます。
ここではプロジェクト名は「WCFRIATest」としました。
Silverlight の設定画面が開きますので「Enable WCF RIA Services」にチェックを入れます。毎度のことで申し訳ないのですが、私の環境は英語版なので、適当に日本語にマップしてください。
プロジェクトが開いたら、データソースを追加します。
2.データソースを定義
データソースを追加ですが、これは(Silverlightプロジェクト(WCFRIATest)ではなく)Webプロジェクト(WCFRIATest.Web)に対して追加します。間違ってSilverlightプロジェクトに追加しようと思ってもデータソースが見つかりませんので・・・。
ここからの手順は、各所で説明しつくされた感がある手順ですが、一応記述しておきます。データソースとしては、なんでもいいのですが、ADO .NET Entity Framework を利用します。
プロジェクトから追加を選びます。
ADO.NET Entity Data Model を選びます。名前は何でもいいです。
Database から作る的なのを選びます。
接続したいDBを選びます。私は、SQL Azure につないでます。
取り込むテーブルなどを選びます。とりあえず全部。
3.データソースに対するDomain Service (DBにアクセスするクラス)を定義
データソースと同じく、プロジェクトから追加を選び、Webカテゴリの中からDomaian Service Class を選びます。
対象とするEntitiesを選びます。とりあえず全部。ODataのときのEndpoint を公開したい場合もここで定義します。
完成したプロジェクトのファイル。3つファイルが増えています。metadata.csについてはここkでは説明しませんが、大したもんではありません。
VSでData Source を表示させ、ドラッグアンドドロップすれば、よくあるデモです。動作確認を含め一度「F5」を押して実行しておきましょう。
無事表示されています。
本題はここからです。
ドラッグアンドドロップではなく、C#からこれらのオブジェクトを制御するにはどうしたらいいでしょうか。
テキストボックスを1つ配置し、1行目の2列目(上記では0.00779と表示されているところ)を表示してみたいと思います。
コードはこんな感じ、、
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using WCFRIATest.Web;
namespace WCFRIATest
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
//Domain Service を利用
dstest context = new dstest();
//実行するも非同期
var load = context.Load(context.GetEnvradiotableQuery());
//デリゲートでロードイベントを登録
load.Completed += (sender, ex) =>
{
//Linq とりあえず1個とってきます。
var query = (from p in context.envradiotables
select p).Take(1);
//実行+表示
foreach (var q in query)
{
textBox1.Text = q.radio_ave.ToString();
}
};
}
//ドラッグアンドドロップの際にVSが勝手に作ったコード
private void envradiotableDomainDataSource_LoadedData(object sender, System.Windows.Controls.LoadedDataEventArgs e)
{
if (e.HasError)
{
System.Windows.MessageBox.Show(e.Error.ToString(), "Load Error", System.Windows.MessageBoxButton.OK);
e.MarkErrorAsHandled();
}
}
}
}
いつもの完全コピペ。
ポイントとしては、非同期実行になること。そして、そのイベントの取得の仕方。わかってしまえば何でもない話。
では、再度「F5」にて実行してみます。
表示されています。
簡単ではありますが、以上です。