3層データバインド
ASP.NET Webフォームアプリケーションのデータバインドは、その実装方法により「2層データバインド」と「3層データバインド」に分類できます。
2層データバインドと3層データバインド
2層データバインドとは、データバインドコントロールとSqlDataSourceコントロール、LinqDataSourceコントロール、EntityDataSourceコントロールなどの「コントロール自体が直接データアクセスを行うデータソースコントロール」を利用したデータバインドのことです。プレゼンテーション層とデータ層の2層でデータバインドを行うことから、そのように呼ばれます。
構造がシンプルなためか、ASP.NET Webフォームアプリケーションの入門記事では2層データバインドを使ったものがよく紹介されているので、目にしたことがある方も多いのではないかと思います。
これに対し3層データバインドは、データバインドコントロールとObjectDataSourceコントロール(プレゼンテーション層)、ObjectDataSourceコントロールから呼び出すロジック層(※注1)、データ層の3層でデータバインドを行い、プレゼンテーション層から直接データアクセスを行わないようにする方法です。
ロジック層は、その内部でさらにビジネスロジックを実装するビジネスロジック層(BLL:Business Logic Layer)と、実際にデータアクセスを行うデータアクセス層(DAL:Data Access Layer)に分けるのが一般的です。後ほど改めて詳しく説明します。
2層データバインドの問題
見た目はシンプルな2層データバインドですが、実際にアプリケーションを作成していく上では少し問題があります。
以下のコード例で説明しましょう。これはTextBoxコントロールで入力した場所名を条件に、EntityDataSourceコントロールを使い、データを取得する例です。
<asp:TextBox ID="LocationNameTextBox" runat="server"></asp:TextBox> <asp:EntityDataSource ID="LocationsEntityDataSource" runat="server" ContextTypeName="DAL.MRRSEntities" EntitySetName="Locations" Where="it.LocationName like '%' + @LocationName + '%'"> <%-- (1) --%> <WhereParameters> <asp:ControlParameter ControlID="LocationNameTextBox" Name="LocationName" PropertyName="Text" Type="String" DefaultValue="%" /> <%-- (2) --%> </WhereParameters> </asp:EntityDataSource>
このコードの何が問題かというと、ビューにビジネスロジックが埋め込まれていることが問題になります。具体的には次の通りです。
- ビューにEntity SQLが直接記載されている
- 検索条件を指定しなかった時の扱いがビューに直接記載されている
例で用いたEntityDataSourceコントロールを始め、2層データバインドに用いるデータソースコントロールを使用する場合、検索条件や抽出項目などをaspxファイルに直接記述する必要があります。そのため、本来データの入力、表示を行うためのビューであるaspxファイルに、ビジネスロジックが入り込んでしまうのです。
このような構造にすると、ビジネスロジックを変更するには、必ずビューを変更する必要が生じてしまい、保守性に難があります。そして、データアクセステクノロジを変更したくても、ビューが従来のデータアクセステクノロジに固定されてしまうため、簡単には変更できません。
また、ビジネスロジックをテストするには必ずアプリケーションを動作させなければならず、コードによる自動化テストの恩恵を受けることができません。
その他にも、記述したEntity SQLはコンパイラによる構文チェックは行われません。これも開発効率低下の一因となります。たったこれだけのコードですが、2層データバインドでは多くの問題を抱えていることが分かったのではないかと思います。
3層データバインドを用いるべき理由
2層データバインドはこういった問題があるため、実際にアプリケーションを開発する際には、3層データバインドを主に使用することをお勧めします。3層データバインドを用いることで、問題は以下のように解決されます。
ビジネスロジックがビューから分離される
ビジネスロジックは専用のクラスに切り出すことになり、ビューには表示に関する情報のみが残ります。
また、切り出したクラスはコードによる自動化テストを行うことも可能であるため、構造は複雑になりますが開発効率の向上が見込めます。
ビジネスロジックのコンパイルチェックが行える
当然ビジネスロジックを切り出したクラスはコンパイラによる構文チェックが行われるため、コーディングミスにいち早く気付くことができます。
ただ、ビジネスロジックの中でもEntity SQLを使えば同じようにコンパイラがチェックできませんので、Linq to Entityなどのコンパイル可能なテクノロジーを使えるなら、なるべくそちらを使うようにしましょう。もちろん、パフォーマンスなどの問題があれば、SQLを直接記載するなどの方法をとる必要があるので、必ずコンパイル可能にしなければいけないというものではありません。