-
Notifications
You must be signed in to change notification settings - Fork 49
UserGuide_BetterUse&FAQ.ja
2016年10月3日
- Open 棟梁を用いたアプリケーション開発を行う、SE・開発者
本ドキュメントは、フレームワークのベターユースについて纏めています。
本ドキュメントに記載の会社名・商品名は、各社の商標または登録商標です。
本ドキュメントは、クリエイティブ・コモンズ CC BY 2.1 JP ライセンスの下で利用可能です。
※ 本ページのコード図の多くは元 Word 資料から抽出できなかったため、キャプションのみとしています。サンプル コードの詳細は付属のサンプル プログラムおよび元資料を参照してください。
- イベント処理の B層:1 画面に 1 つ作成を基本とする。各イベント処理はコントロール名をメソッド名に使用すると良い。(図1.1.1)
- 共通部品の B層:システムで 1 つ、または共通部品の区分毎に 1 つ作成を基本とする。区分名をメソッド名に使用すると良い。(図1.1.2)
図 1.1.1 B層クラスの分割例(イベント処理)
図 1.1.2 B層クラスの分割例(共通部品)
- イベント処理の場合:1 画面に 1 つ作成を基本とし、複雑でイベント数の多い画面ではいくつかのクラスに分けて作成すると良い。
- 共通部品の場合:共通部品の区分毎に 1 つ、または共通部品毎に 1 つ作成を基本とする。
D層 (Dao) クラスの作成基準は以下に従うと良いでしょう。
- 個別に Dao クラスを使用:インテリジェンスな D層クラス [1] が必要なら、機能毎に「自作 Dao クラス」を実装する。
- 汎用的な Dao クラスを使用:入力したパラメタをそのまま設定するだけで実行できる SQL の場合は、汎用インターフェイスを持つ「共通 Dao クラス」を使用する (4.6 節参照)。
- 自動生成した Dao クラスを使用:D層自動生成ツールでテーブル単位の CRUD 部品を自動生成し、更新系処理はこの「自動生成 Dao クラス」を使用する。
- 集約する場合:B層から「共通 Dao クラス」「自動生成 Dao クラス」を集約して使用する「Dao 集約クラス」も可能。「データアクセス制御クラス」を引き継ぐ必要がある。(図1.3)
- 2.1 P層イベント処理の対象外のイベント:ClientCallback によるサーバ側イベントなど。この場合、イベント処理から B層・D層を直接呼び出す (B層のエラー処理・トランザクション管理・ログ出力は正常に機能する)。
- 2.2 P層イベント処理の対象コントロール イベント追加:サンプルを流用すればチェックボックス コントロールのチェック チェンジ イベントに対応した状態で利用可能。
-
2.3 不正操作防止機能の局所化:
CanCheckIllegalOperationフラグにより、ページ単位・ボタン単位で局所化が可能。(図2.3-1、図2.3-2) - 2.4 暫くお待ちくださいダイアログの一時無効化:ポストバックのダウンロード処理などで、ダウンロード処理を行うポストバック ボタンに JavaScript を実装して抑止する。(図2.4)
- 2.5 IFRAME へのダウンロード処理(二重送信防止機能の一時無効化):IFRAME へのダウンロード時、「二重送信防止機能」により操作が抑止され続ける場合、処理を実装して一時的にキャンセルする。(図2.5)
-
2.6 セッションの削除方法:「Session タイムアウト検出機能」使用時に
Session.Abandon()を呼ぶと必ず Session タイムアウト例外が発生する。例外を発生させないにはthis(BaseController).FxSessionAbandon()を使用し、検出用 Cookie を削除 [2] してから解放する。ただし実行後に同一画面でポストバックすると「不正操作防止機能」エラーになるため、解放後はメニュー画面等へ Get 画面で遷移すること。(図2.6)
表 2.7 ダウンロード処理の推奨方式(FAQ 抜粋)
| 項番 | 問題 | 対応 |
|---|---|---|
| 1 | ファイルをダウンロードした場合、Loading... ダイアログの表示が消えない。 | JavaScript の Loading... ダイアログ表示機能に起因。ダウンロード前に JavaScript でこの機能を無効にする (最新版ではフラグで一時無効化可能、2.4 節参照)。または別ウィンドウ/IFRAME (EnableViewState=False) からのリクエストでファイルをレスポンスする。 |
| 2 | ダウンロード後の操作で不正操作例外が発生する。 | 不正操作防止機能に起因。config 設定で無効にする (最新版では画面プロパティで局所化可能、2.3 節参照)。または別ウィンドウ/IFRAME を使用する。 |
| 3 | Yes/No ダイアログの Yes/No クリックでダウンロードすると、次の PostBack でも Yes/No のイベント ハンドラが動作する。 | Submit フラグが更新されないために発生。別ウィンドウ/IFRAME を使用する (不正操作防止機能の局所化には Submit フラグが利用できる)。 |
| 4 | ダウンロード後に任意のアプリでファイルを開けない。 | キャッシュ無効化の HTTP ヘッダが付与されている可能性。ダウンロード前に Response.Clear() で HTTP ヘッダをクリアしてから、キャッシュ・コントロールの HTTP ヘッダを再設定する。 |
| 5 | IFRAME の更新後に IFRAME 親画面の操作ができなくなる。 | readyState が complete にならず interactive になるため、二重送信防止機能により操作が抑止され続けることに起因。2.5 節の方法で対策可能。 |
| 6 | 別ウィンドウ・ダイアログ表示の際にポストバックが発生する。 | 仕様上、ShowNormalScreen()/ShowModalScreen() でフラグを立てクライアント側から起動するため。最新版ではクライアント側 JS から直接起動する GetScriptToShowNormalScreen()/GetScriptToShowModalScreen() を追加。 |
手動のトランザクション管理や、2 層 C/S で 2 本目のコネクションを必要とする場合などは、データアクセス制御クラス (Dam) を手動で生成して、コネクション・トランザクションを管理します。トランザクション・コネクションの解放処理 (CommitTransaction、ConnectionClose メソッド) には try...catch...finally を使用しても良いですが、通常 GC により解放される場合、トランザクションはロールバックされ、コネクションも切断 (または接続プールに戻る) されます。(図3.1)
動的 SQL には動的パラメタライズド・クエリが有効です。条件検索 + あいまい検索という複雑な SQL でも、SQL 定義 (XML) とプログラムで容易に対応可能です。(図4.1-1:SQL 定義、図4.1-2:D層のプログラム)
図 4.1-2 D層のプログラム(VB)
検索条件の「パラメタのデータ型」と「DB の列のデータ型」が不一致になると、列のデータがパラメタのデータ型にキャストされて検索されます (「暗黙の型変換」)。これが発生するとインデックスが正しく使われず、性能が大きく劣化します。
本フレームワークでは、SetParameter メソッドからパラメタのデータ型を指定できますが、データ型の明示が必要になるのは「暗黙の型変換」が発生した場合のみです。通常はデータ型を明示せず、性能劣化が確認された場合に外出しの SQL ファイルを編集 (パラメタのデータ型を SQL 内でキャスト) する方法を推奨します。
※ 動的パラメタライズド・クエリの「LIST タグ」を使用した場合は、パラメタが自動展開されるため SQL ファイル編集で対策できません。この場合は API からデータ型を明示するか、「LIST タグ」ではなく「VAL タグ」を使い、各 DBMS の変換関数を仕掛けたパラメタを必要な数だけ埋め込んで対処します。
.NET の CommandBuilder による自動生成バッチ更新用 DataAdapter は、テーブル単位の SELECT にしか対応しない、タイムスタンプアンマッチ行が把握できない、IDENTITY 列も INSERT に含める、全列比較の楽観排他で性能問題がある、などの問題があり、本フレームワークではサポートしません (マスタメンテなど限られた範囲では有効)。
代わりに、AcceptChanges メソッド [5] と DataRow の RowState プロパティ (Added/Modified/Deleted)、DataRowVersion.Original [6] を活用してバッチ更新を実装します。自動生成した CRUD 用 Dao を利用すると更に容易です。サンプルは ~\root\programs\C#\Samples\2CS_sample\DenDaoAndBatUpd_sample にあります。編集中の DataSet/DataTable を Session に保持するため、サーバ メモリの消費量に注意します。
本フレームワークではストアド プロシージャの実行も可能です。「戻り値」の例では Parameter.Direction プロパティに ParameterDirection.ReturnValue を指定します (出力パラメタは .Output/.InputOutput)。最新版では、コマンド オブジェクトを直接参照しなくても GetParameter メソッドで取得可能です。
図 4.4-1 ストアド プロシージャの実行サンプル(SqlClient での例)
本フレームワークでは ODP.NET でサポートされる「配列バインド [7]」の実行も可能です。
図 4.5 配列バインド(ODP.NET)の実行サンプル
Dam の取得方法:B層では ((DamOraOdp)this.GetDam())、「Dao 集約クラス」では ((DamOraOdp)this.Dam)、「自作 Dao クラス」では ((DamOraOdp)this._dam)。「共通 Dao クラス」「自動生成 Dao クラス」で配列バインドを行う場合はカスタマイズが必要です。
汎用的な Dao クラスとして [Touryo].Infrastructure.Business.Dao 名前空間の「共通 Dao クラス」(CmnDao) を利用できます。主に参照系の処理を実行し、必要に応じてカスタマイズ可能です。ストアド プロシージャ (参照/更新) の実行も可能です。(図4.6-1、図4.6-2)
動的パラメタライズド・クエリは XML 編集を伴うため、タグ数が多い場合 (100 タグ以上が目安) 性能が劣化することがあります。一度実行すると内部的に XML から SQL に変換されるため、この SQL を保持する Dam を再利用すれば連続実行の性能を向上できます。ただし一度実行すると Command オブジェクトにパラメタが残るため、Command.Parameters.Clear() でクリアしてから再設定する必要があります。「共通 Dao クラス」「自動生成 Dao クラス」では実行の度に SQL が再設定されるため、「自作 Dao クラス」で実行するか、SQL を再設定しないメソッドを追加実装する必要があります [8]。(図4.7)
フレームワーク経由の実行は 1 件あたり約 0.5m 秒のオーバヘッドがあるため、必要に応じて Transact-SQL、ADO.NET 直実行、配列バインド、または INSERT/UPDATE のバッチ実行方式を検討します。これらをサポートするクラス・メソッドとして、Touryo.Infrastructure.Public.Db.SQLUtility クラス、Touryo.Infrastructure.Framework.Dao.BaseDao.ExecGenerateSQL メソッドを追加してあります (現状 SQL Server のみ、Oracle・HiRDB は配列バインドを使用)。(図4.8)
-
4.8.1 SQLUtility クラス:
GetInsertSQLParts、GetUpdateSQLPartsメソッドでバッチ処理用の SQL パーツを生成できます。(図4.8.1-1、図4.8.1-2) -
4.8.2 ExecGenerateSQL メソッド:
BaseDamクラス [9] のExecGenerateSQLメソッドで、SQL を実行しないで SQL のみ生成できます (詳細は RerunnableBatch_sample2 を参照)。(図4.8.2)
D層処理のデバッグ実行中などに 'System.Xml.XmlException' の初回例外が System.Xml.dll で発生しました。 と表示されることがあります。これは、動的パラメタライズド・クエリのチェック ロジック内で XML フォーマットに違反するコマンド (通常の SQL や静的パラメタライズド・クエリなど) が指定された場合に出力されるメッセージで、品質には問題ありません。
ASP.NET Mobile Web 開発では、P層フレームワーク (Mobile Web 開発用)、B層フレームワーク、D層フレームワークを使用できます。サンプルは ~\root\programs\C#\Samples\WebApp_sample\ProjectXM_sample にあります。
図 5-1 ASP.NET Mobile Web 開発用の P層フレームワークを使用(継承)
- P層フレームワークの継承:「画面コード親クラス1」に Mobile Web 開発用のクラスを使用し、「画面コード親クラス2」がそれを継承、「画面コード クラス」が更にそれを継承する。
-
P層イベント処理:マスタ ページは存在しないため、各 MobilePage 上の個別イベント処理のみ実装可能。サポートするコントロールは Command コントロール、イベントは Click イベントのみ (コントロール名:
[prefix]任意の文字列、イベント ハンドラ名:UOC_cmdCommand_Click、prefix = cmd)。 - 使用できない機能:ダイアログ表示機能、セッション管理機能 (親画面別/ブラウザ ウィンドウ別セッション領域、セッション タイムアウト検出)、二重送信防止機能、画面遷移制御機能、Ajax/ClientCallback 機能、その他 JavaScript のユーティリティ機能。
- 必要なコンフィグレーション:cookie をサポートしない端末があるため、web.config を cookie 未サポート考慮の設定に変更する。app.config は使用できない機能のパラメタが不要になり、Command コントロール数を定義するパラメタを追加する。詳細はサンプルの web.config/app.config を参照 (パラメタの説明は「纏め者編」1.2 節)。
ACCESS ログは正常系・異常系の形式で出力されます (図6.1-1:正常系、図6.1-2:異常系)。P層側でのスタック トレースの出力は B層のスタック トレース情報を含まないため、B層でエラーが発生した場合は B側のエラー情報のスタック トレースを確認します。
図 6.1-2 ACCESS ログ(異常系)
SQL トレース ログも正常系・異常系の形式で出力されます。エラー発生時のログも出力されるためデバッグに活用でき、DBMS に投げている SQL に問題がないか確認にも利用できます。SQL ファイルとログの対応をとる場合、コメントにファイル名を入力しておくと良いでしょう。
[(ログ ヘッダー)],[INFO ],[1],(実行時間),(CPU時間),[(〇)正常終了],
[commandText]:--ShipperCount.sql SELECT COUNT(*) FROM Shippers,[commandParameter]:
以下、要件毎の対応方法や、問い合わせ対応を FAQ 化したものです。Open 棟梁は柔軟性が高く、殆どの要件に対応可能です。
| 質問 | 回答 |
|---|---|
| 複数画面対応の Web アプリケーションに対応しているか? | どのようなパターンでも対応可能。複数画面対応の開発を支援する機能を活用できる。 |
| クロス ブラウザに対応しているか? | IE6/7/8、Firefox、Safari、Chrome、Opera で動作確認。制限事項:業務モーダル ダイアログの表示のみ IE 限定 (OK、Yes/No メッセージ ダイアログはクロス ブラウザ対応、ただし Opera はダイアログ未対応)。LinkButton、ImageMap など href の __doPostBack() を使うコントロールで二重送信防止機能が IE6 のみ有効にならない。 |
| Internet 系で Session タイムアウト時も処理を続行させたい。 | Session タイムアウト検出機能と、Session を継続的に使用するフレームワーク機能 (セッション領域の自動削除、ボタン履歴情報記録、不正操作防止) を全て OFF にすることで対応できる。 |
| 負荷分散クラスタでフェイル オーバー後、業務続行可能か? | SQL Server/Oracle いずれかの Session モードを選択し、専用の Session 状態保持用サーバを新設すれば可能 (二重化できない StateServer は選択肢から除外)。 |
| マスタ ページの利用は必須か? | 基盤の定義をマスタ ページに持つため必須。ただし基盤の定義以外は空のマスタ ページでも問題ない。 |
| マスタ ページのネストをサポートしているか? | 最新バージョンでサポート。 |
| P層イベント処理機能の対応コントロールを追加したい。 | コントロールのプレフィックスでハンドルするようになっており、ベースクラス2のコントロール取得処理や中継イベント ハンドラをカスタマイズすることで追加できる。 |
| P層イベント処理機能をキャンセルしたい。 |
*.config に指定するコントロール毎のプレフィックスを空に指定すればキャンセルできる。 |
| ログイン画面で Session タイムアウト例外が発生する。 | P層フレームワークは Session を必要とするため、Internet 環境下のログイン画面には使用しないか、Windows 認証や専用認証基盤 (SiteMinder 等) を利用する。IsNoSession フラグを true にすると当該画面でボタン履歴記録・不正操作防止を OFF にできる。 |
| ダウンロード関連 (#10〜14) | 2.7 節参照。 |
| OK、Yes/No ダイアログのメッセージに改行が入らない。 | メッセージ文字列に含まれる改行コードを <br/> に変更する。 |
| HTML のタイトルは何処で指定しているか? | ベースクラス2の CMN_FormInit メソッドで this.Page.Title に設定。 |
| Ajax、jQuery のタブ切り替えがうまく動かない。 | ViewState が無いためポストバックの都度、初期化処理が必要。初期化処理から Fx_Document_OnLoad() を SetTimeout() で時間差を付けて呼び出すなどの対策が必要 (最新版では対応済み)。 |
| P層イベント処理機能は Web ユーザ コントロールをサポートしているか? | 最新版でサポート。ページ側と Web ユーザ コントロール/マスタ ページのコントロール名称が衝突しないようプレフィックス追加などを検討する。 |
| 予期せぬ Session タイムアウト例外が発生する。 |
Session.Abandon() に加え、Session タイムアウト検出用 Cookie の削除も併せて行う (最新版では this.FxSessionAbandon() に集約)。 |
| ASP.NET4.0 の新しい HTML 出力に対応しているか? | web.config に <pages controlRenderingCompatibilityVersion="3.5" /> を付与するか、common.js を同梱の別のものに差し替える。clientIDMode="AutoID" が前提。 |
| ASP.NET MVC に対応しているか? | 対応していない。P層以外の B層・D層フレームワークや通信制御機能などは利用可能。 |
| 質問 | 回答 |
|---|---|
| リッチクライアントに対応しているか? | Windows Forms、WPF/XBAP、Silverlight、Windows ストアアプリに対応。このうち P層フレームワークは Windows Forms のみサポート。 |
| Windows Forms の P層でイベント処理対応コントロール・イベントが多くなり過ぎる。 | ベースクラス2のカスタマイズで追加可能だがカスタマイズ量が多くなるため、.NET 標準のイベントハンドラから隠しボタン (HiddenButton) の DoClick メソッドで Click イベントを発生させることも可能。 |
| MenuItem コントロール・イベントは P層イベント処理機能にサポートしているか? | サポート。検索方法が他と異なるためベースクラス2をカスタマイズせず、UOC_FormInit で MenuItem の Click イベントに共通 Click イベント ハンドラ (Item_Click) を設定する。 |
| 質問 | 回答 |
|---|---|
| 1 クラス 1 メソッドになってしまわないか? | 既定の入口は DoBusiness() の 1 つだが、内部で if/select 振り分けを行うか、レイトバインド機能による振り分け機能付きベースクラス2を利用する (現在は振り分け機能付きが既定方式)。 |
| B、D層を設けるのが面倒。 | P層で Dam を直接生成してデータアクセスすることも可能 (P層のみ or P・D層)。D層に共通 Dao/自動生成 Dao を使用すれば自作 Dao の開発を割愛できる。 |
| トランザクション管理の実装は? | B層ベースクラス2の UOC_ConnectionOpen() でトランザクションを開始し、B層処理完了時にフレームワーク側で自動的にコミット or ロールバックする (例外発生時は自動ロールバック)。2 層 C/S では開始のみ自動化。 |
| 分割コミットなどは可能か? |
this.GetDam().CommitTransaction(); this.GetDam().BeginTransaction(); を B層から呼び出すことで可能。 |
| 手動のトランザクション管理は可能か? | Dam を直接生成してデータアクセスすることで可能。2C/S 用フレームワークでは 2 本目の接続が可能。 |
| 質問 | 回答 |
|---|---|
| バインド変数へのバインド方法は? | 名前バインドにのみ対応。順番バインドはサポートしない。OLEDB、ODBC、HiRDB では、コメント中にパラメタ記号を含むパラメタ名と同じ文字列があると正しく動作しない。 |
| ストアド プロシージャ、無名 PL/SQL ブロックの実行や戻り値の取得は可能か? | 最新版では動的パラメタライズド・クエリ機能を使用できる。 |
| ODP.NET、HiRDB の配列バインドをサポートしているか? | サポート。 |
| LINQ to SQL/Oracle/Entities をサポートしているか? | サポートしない。D層フレームワークの使用を推奨 (LINQ to Object/XML/DataSet など DB アクセス以外の LINQ は問題ない)。 |
| IN 句に複数のパラメタを指定したい。 | 動的パラメタライズド・クエリの LIST タグを使用 (SetUserParameter() による文字列置換でも代替可能)。 |
| 検索条件の IN 句 (副問合せ) を動的化したいがエラーになる。 | IF タグではなく、タグのネストが可能な SUB タグを使用する。 |
| デッドロック、ロックタイムアウト、キー重複などの例外をリトライしたい。 | B層ベースクラス2の例外処理をカスタマイズし、リトライ対象例外を業務例外に振り替えて P層に正常系の戻り値を戻す。 |
| コマンド タイムアウト値を設定するには? | 最新版では共通のコマンド タイムアウト値を *.config に設定できる。 |
| SQL で暗黙の型変換が発生し性能劣化する。 |
SetParameter() のオーバーロードで型・サイズを指定可能。SQL 定義ファイル中に型キャストを明示することでも対応可能 (4.2 節参照)。 |
| XML ファイルのサイズなどにより性能が劣化しないか? | 1 つの XML に 150 タグ以上あると性能劣化が始まるため不要なタグは記述しない。バッチ更新はラウンドトリップ軽減のため配列バインドを併用する。PARAM/DIV タグは性能劣化の原因にならない。 |
| Like 句を使用した曖昧検索をサポートしているか? | サポート。パラメタにワイルドカードを含めた Like の検索条件を渡す (D層自動生成ツールの生成物は非対応)。 |
| パラメタライズド・クエリの初歩 | Like 検索は標準・動的パラメタライズド・クエリでサポート。null を渡したい場合は DBNull を使用する (動的では null は特殊な制御パラメタ)。テキスト内パラメタとタグ内パラメタが混在する場合はテキスト内パラメタが優先される。 |
| 質問 | 回答 |
|---|---|
| プロキシ経由やプロキシ認証をサポートしているか? | サポート。プロキシへの URL や Credentials を XML 定義ファイルに指定可能 (API から直接指定も可能)。 |
| Windows 認証を使用した SSO をサポートしているか? | サポート。ケルベロス認証をサポートし、ダブル〜トリプル ホップも可能 (ベース クライアント セキュリティ モデルは通常推奨しない)。 |
| WCF-TCP/IP などの通信プロトコルはサポートしているか? | サポート。サービス インターフェイス、サービス プロキシを追加開発することで対応可能。 |
| 質問 | 回答 |
|---|---|
| ログ出力機能で 1 系 ⇔ 2 系のローリングを実現可能か? | log4net の類似機能 (MaxSizeRollBackups、CountDirection) で代替する。 |
| ログ出力でユーザ毎に異なるファイル出力が可能か? | リッチクライアント (特にターミナルサービス) では、ファイル出力のアペンダ設定に <param name="File" value="${USERPROFILE}\Log\ACCESS" /> と記述する。 |
| 同一プロセス毎に多重起動に対応する方法は? | 環境変数や PID などの変数を利用する (log4net.Util.PatternString の %processid など)。 |
| リッチクライアントの定義ファイルの保存先にユーザ毎に異なるディレクトリを指定可能か? | 環境変数を使用してデータ保存先を選択できる (リソースローダ部品のパスに %USERPROFILE%\AppData を指定)。 |
| ASP.NET の web.config/app.config への変更の反映タイミングは? | web.config は変更されると自動的に IIS が再起動し直ちに反映。app.config は IIS が再起動しないため iisreset コマンドで手動反映する。 |
| Forms 認証ログイン前に JS ファイルなどを参照できない。 | web.config に <location path="Framework/Js"> で <allow users="*"/> を追加し、JavaScript ファイルを認証対象外にする。 |
| .NET Framework Client Profile で動作&コンパイルできない。 | Client Profile はサポートしない (存在しないサーバサイド API を多数使用しているため。Client Profile は 4.5 でドロップされた)。 |
- インテリジェンスな D層 (Dao) クラス。
- Session タイムアウト検出用 Cookie を削除する。
- 「パラメタのデータ型」(nvarchar) と「DB の列のデータ型」(varchar) が不一致。
- SQL Server の Transact-SQL の変換関数。
- DataSet/DataTable の AcceptChanges メソッド。
- 楽観排他に利用するオリジナル データを取得する。
- ODP.NET でサポートされる配列バインド。
- 共通 Dao/自動生成 Dao (テンプレート) を修正する。
- BaseDam クラス。
-以上-