本ユースケースでは、従業員テーブルを利用します。関連テーブルを抜粋したER図を次に示します。実際には図に表記していない多数の関連テーブルが存在します。本稿ではこちらの図の中でもさらに、次の5つのテーブルのみを扱うものとします。BusinessEntityPersonEmployeeGenderMaritalStatusEmployeeテーブルにGenderとMaritalStatusというカラムがありますが、この中身にはコードが設定されています。TableEmployee表示する値はそれぞれ、GenderテーブルとMaritalStatusテーブルに格納されているため、表示する際にはそちらの値に置き換える必要があります。TableMasters本ユースケースでは、BusinessEntity、Person、Employeeの三つのテーブルを次のように結合した、ManagedEmployeeというビューから値を取得します。Person.BusinessEntityIDデータ取得処理時にテーブルを結合するのではなく、結合済みのビューに対してデータ取得処理行うことで、次のような利点を得られます。Mapperから扱いやすくなるインデックス付きビューなどを利用できる可能性があるManagedEmployeeにも、Employeeと同様にGenderとMaritalStatusのコードのみを持ちます。このため画面で表示する際にそれらのマスターテーブルから値を取得して表示することとします。一覧画面で編集しない場合は、データベースのビューに表示名を入れると実装がより容易になります。今回はグリッド上で編集も行います。その際、GenderやMaritalStatusはコンボボックスで取り扱うため、表示名はデータベースのビューには入れず、それぞれのマスターから取得して表示時に置き換えることとします。次のシーケンス図が、「従業員を閲覧する」ユースケースのクライアントサイドの処理概要になります。ユースケース「従業員を閲覧する」:クライアントサイド左から3レーン目のManagedEmployeeListViewModelからIHumanResourcesServiceを3回呼び出し、次の値を取得していることが見て取れます。全従業員一覧これらを取得したのちに、一覧画面を表示します。先にも説明した通り、従業員を表すManagedEmployeeクラスでは、GenderとMaritalStatusはコードしか保持していないため、1.と2.で表示値を取得しています。その際に、編集機能でプルダウンで編集できるよう、選択可能な値をすべてここで取得しています。注目していただきたいポイントの一つが、WCFサービスから取得されてきたManagedEmployeeをManagedEmployeeViewModelに詰め替えている箇所です。具体的なコードは次のとおりです。}}ManagedEmployeeをコンストラクタの引数として渡して、ManagedEmployeeViewModelを生成していることが見て取れます。ManagedEmployeeViewModelのコンストラクタの実装が次の通りです。...}ManagedEmployeeクラスとManagedEmployeeViewModelクラスはほとんど同じプロパティで構成されており、Mapperクラスを利用して、ViewModelへ値を詰め替えています。類似のクラスを用意して値を詰め替えているのには理由があります。本システムではグリッド上で従業員の追加・編集処理を行います。何れかを表す状態プロパティが必要です。サービスから取得したクラスには当然、ユーザーインターフェースの実現のみに必要なプロパティは存在しないため、専用のViewModelを作成して値を詰め替えて表示します。このような理由以外にも、次のようなケースでもViewModelへの詰め替えが必要になることがあります。対して、GenderとMaritalStatusは、編集やユーザーインターフェース上の特殊な処理を想定しておらず、ViewModelへの詰め替え処理は行わないで、そのまま利用します。WPFのGcSpreadGridコンポーネントのItemsSourceプロパティにManagedEmployeeViewModelのコレクションをバインドします。次のコードが、実際のバインドしているコードの抜粋です。...今回はSPREADの設定にデザイナーを使わず、XAMLで記述する方式を取りました。これは別にXAMLが特に優れているからという訳ではなく、リファレンスとしてお見せするのにXAMLのほうが都合が良いというのが理由です。実際にはXAMLかデザイナー(もしくは、お勧めしませんがコードビハインドでC#)の何れで実装するかは、各々のプロジェクトで判断する必要があるでしょう。前述のXAMLについて、四つほど見ていただきたいポイントがあります。一つは、GcSpreadGridのプロパティのLockedとProtectedにViewModelのIsReadOnlyプロパティをバインドしている個所です。ViewModel側でデフォルトではtrueが設定されています。することで、読み取り専用となるように制御しています。続いてProtectedのすぐ下のCanUserSortColumnsとCanUserFilterColumns、ColumnDragModeの三つのプロパティです。これは全ての列でソートとフィルタリングを有効にし、選択した列をドラッグで移動可能にしています。実際の振る舞いは後程見ていただきましょう。三つ目がGcSpreadGrid.Columns以降です。列は動的生成することも可能ですが、列の順序を制御したり、列ヘッダーの名称を日本語名で表示するためには、個別に列を定義する必要があります。実際には多数の列が定義されていますが、ここではFirstNameとGenderの列のみ記載しています。FirstNameはTextCellTypeを、GenderにはComboBoxCellTypeを指定しています。GenderのComboBoxCellTypeでは、表示値をGenderオブジェクトのNameプロパティを採用し、選択値にはCodeプロパティを採用するように定義しています。四つ目がSetItemsSourceBehaviorです。これは本システムで作成したもので、ComboBoxCellTypeのItemsSourceへデータベースから取得したGenderのリストをバインディングしています。WPFのComboBoxCellTypeはBindableObjectを継承していない関係で、ItemsSourceへ直接値をバインドすることができません。コードビハインドから設定することも可能ではありますが、XAMLからバインドするためにSetItemsSourceBehaviorを作成しました。良かったらコードを参考にしてみてください。SetItemsSourceBehavior.csクライアントサイドについては以上です。続いてサーバーサイドの実装も見てみましょう。次のシーケンスがサーバーサイドの流れになります。ユースケース「従業員を閲覧する」:サーバーサイドとくに見ていただきたいのが、AOPで「織り込まれる」InterceptorがTransactionInterceptorに加えて、AuthenticationInterceptorが増えていることです。コードを見てみましょう。}}先に開設したAuthenticationServiceとほぼ同じロジックになっています。AuthenticationServiceのAuthenticateメソッド以外は、実行時に利用者の認証処理を行います。これは不明なユーザーによってWCFサービスが実行されることを排除するためです。このようにAOPを利用することによって、抜け漏れなく、かつ重複したコードもない、堅牢で生産性の高いサービスを構築することが可能となります。DataAccess層の実装は、認証ユースケースと差がないため説明は割愛します。実際の動作を見てみましょう。列クリックでのソートやフィルタリング、列を選択して列順の入れ替えが正しく動作しています。Genderがコードではなく、名称が表示されていることが見て取れるでしょう。金融ソリューション開発部所属。圧縮・解凍UNIX基本講座@CodeZine『CodeZine(コードジン)』の公式アカウントです。【NEW】デブスト2019デブサミ2019福岡・関西デブサミ2019夏デブスト関西デブサミ2019×ログインEメールパスワード※旧SEメンバーシップ会員の方は、同じ登録情報(Eメール&パスワード)でログインいただけます。イラストの無断転載を禁じます。記載されているロゴ、システム名、製品名は各社及び商標権者の登録商標あるいは商標です。