ラベル クエリ の投稿を表示しています。 すべての投稿を表示
ラベル クエリ の投稿を表示しています。 すべての投稿を表示

2011年9月30日金曜日

◆クエリーとのデータ連結

LightSwitchではテーブル同士の(というかEntity同士)のリレーションは、データソースのテーブルに外部キーが設定してあれば自動的に張られる。

そのデータソースを基にすれば、簡単にテーブル同士が連携した画面を作ることが出来る。
しかし、実アプリケーションでは単純にテーブルの全データを使うのではなく、ある条件で絞り込んだ上で使用することが多い。(例えば、削除フラグが立っているデータは除くとか)

Accessとかであればテーブルとクエリを連結したり、クエリ同士を連結したりということがGUIで簡単にできる。

LightSwitchでこれを実現するにはいくぶん直感的でない作業が必要になるので、その方法を纏めておく。

<データ>

まずはいつもどおりNorthwindから以下のテーブルを追加してデータソースを作る。

  • Customers
  • Employees
  • Orders
  • Order_Details

2011-09-30 11h51_40

<画面>

テンプレートに「一覧および詳細画面」を指定して画面を作成。
image

実行すると以下のような画面が表示される。
2011-09-30 13h12_54

 

ここで、現在グリッド表示部分は「Orders」テーブルからそのまま表示されているが、これをクエリにしてみる。

<クエリ>

デザイン画面に戻って、左ペインの「Orders」から「クエ入りの編集」リンクをクリックする。
image

表示された「クエリデザイナ」画面にてフィルタを追加する。
ここでは便宜的に以下のフィルタを追加した。
image

これで実行すると以下のように「Ship Via」が「1」で絞りこまれた注文一覧が表示される。
image

これだけで良ければ直感的かつ簡単で良いのだが(実際これでも良いだろう)、ここで使用したクエリは画面レベルのクエリで、他の画面などでは使用できないし、フィルタが追加されていることがデザイン画面では容易に把握できないためある程度の規模になってくると見通しを悪くする可能性がありそうだ。

そこで、これをアプリケーション全体をスコープとするクエリに作り替えてみる。

  1. まずは今作ったフィルタを削除する。
  2. 「ソリューションエクスプローラー」の「Orders」テーブルを右クリックして表示されたメニューから「クエリの追加」を選択する。
    image
  3. クエリの名前を「OrdersByShipVia1」と指定し、先ほどと同じフィルタを追加する。
    2011-09-30 13h38_31
  4. 「ソリューションエクスプローラー」にて「顧客別注文一覧」画面をダブルクリックしてデザイナー画面を表示させる。
  5. デザイナー画面、左ペインの「Orders」を右クリックして表示されたメニューから「削除」をクリックする。
    image
  6. デザイナー画面上部のツールバーにて「データ項目の追加」をクリックし表示された「データ項目の追加」画面にて「OrdersByShipVia1」クエリを選択しOKをクリックする。
    image
  7. 左ペインに追加された「OrdersByShipVia1」を画面ツリーの「Details Column」の下にドラッグして追加する。
    image
  8. これで一旦表示してみると以下のような画面が表示される。
    2011-09-30 13h51_36
  9. 「Ship Via」は1のデータが表示されているが、顧客を選択しなおしても「Orders」のデータが変わらないのが分かる。
    「Customers」と「OrdersByShipVia1」の関連ができていないのである。
    ココらへんがもう少し簡単になれば良いと思うのだが、とりあえず以下のような手順になりそうだ。
  10. 「ソリューションエクスプローラー」にて「OrdersByShipVia1」をダブルクリックしてデザイナー画面を開く。
  11. 表示されたデザイナー画面にてフィルターを以下のように追加編集する。
    (CutsomerIDを使ったパラメータクエリにする)
    image
  12. 「ソリューションエクスプローラー」にて「顧客別注文一覧」をダブルクリックして表示されたデザイン画面の左ペインにて「OrdersShipVia1」の「CustomerID」パラメータを選択する。
    image
  13. 「プロパティ」ウインドウにて「パラメータバインド」をクリックし、表示されたメニューで「Customers」を選択。
    ピリオドを入力し「SelectedItem」を選択。
    ピリオドを入力し「CustomerID」を選択。
    imageimageimage
    これで左ペインを見ると「CustomerID」に矢印が引かれ、連結されたことが分かる。
    image
  14. 以上を実行すると画面は以下のようになる。
    2011-09-30 14h12_35
    こんどは「Customers」の選択に応じて「Orders」の表示が変わるのが分かる。
  15. 最後にレイアウトが今ひとつなので、これを調整する。
    ちなみに、今のレイアウトは以下の状態に成っている。
    2011-09-30 14h15_17
    これは、ルートノード「顧客別注文一覧」の下に4つのノードがあることを表している。
    また、ルートノードは「列のレイアウト」となっているので、子どもの4つのノードは横並びになる。(HorizontalAlighが指定されたStackパネルが使われていると思われる)
  16. データグリッドを以下のようにドラッグし、「Details Column」の子ノードにする。
    image
  17. 以上で実行すると初期表示と同様のレイアウトで表示される。
    2011-09-30 14h25_33

2011年9月24日土曜日

◆クエリでグローバルな定数を使う

クエリデザイナでフィルターを定義する際、日付型に対しては「グローバル」という種類が指定できる。(多分日付型に限った仕掛けでは無いと思うが、さしあたってデフォルトで文字列型や数値型には存在していないようだ)
image

これは予めシステムで定義された定数ということで、以下のようなものが用意されている。
image

これらを使うことでコードを書かなくてもある程度の条件が指定できることになる。

また、これらは独自に追加することも可能であり、以下のような手順になる。

    1. 「ソリューションエクスプローラー」で「論理ビュー」から「ファイル表示」に切り替える。
      image
    2. 「DATA」フォルダにある「ApplicationDefinition.lsml」ファイルを右クリックして「開く」を選択する。
      image
    3. 表示されたXMLファイルに以下のような定義を追加する。
      image
      ここで、「GlobalDates」は任意の名前であるが次に追加するクラス名と同期している必要がある。
      その次の行の「ThreeDaysAgo」がメソッド名になる。
    4. XMLで定義したクラス(メソッド)を「Common」プロジェクトに実装する。
          public class GlobalDates
      {
      public static DateTime ThreeDaysAgo()
      {
      return DateTime.Today.AddDays(-3);
      }

    5. 実装が済んだらVisualStudioを再起動。(デザイナのみを再起動する機能があるような記述もあったが、自分の環境では見当たらなかった)

以上で、クエリ画面を開いてみると以下のように追加した値が表示されるはずだ。
image

◆クエリをカスタマイズする

クエリデザイナでのフィルタの作成は、
2011-09-24 20h12_27
こんな感じなので自ずと限界がある。

そこでLightSwitchではクエリをコーディングでカスタマイズできるようになっている。
前回のサンプルでカスタマイズしたクエリを追加してみる。

  1. 「ソリューションエクスプローラー」で「Customers」テーブルを右クリックして「クエリの追加」を選択する。
    image
  2. 「プロパティ」ウインドウで「名前」に「OrderedCustomer」と入力し、「追加クエリコードの編集」リンクをクリックする。
    image
  3. 表示された「OrderedCustomer_PreprocessQuery」メソッドを以下のようにカスタマイズする。
        public partial class NorthwindDataService
    {
    partial void OrderedCustomer_PreprocessQuery(ref IQueryable<CustomersItem> query)
    {
    query = query.Where(c => c.Orders.Count() > 0);
    }
    }

    ここで、「query」引数はデザイナで定義されたクエリで、これに対してLINQなどで条件を追加していけば良さそうだ。
    ここでは、過去にOrderしたことのある顧客だけを抽出している。

これで実行すると絞り込まれた「CusutomerName」がオートコンプリートボックスに表示される。
2011-09-24 20h27_12