ASP.NET MVC - My MVC Applicationを解析してみる (6)OracleからSQL文でデータを取得する - データアクセス層

ASP.NET My MVC ApplicationはSQL Serverに接続し、ADO.NET Entity Data Modelを
使用してデータを取得しています。

が、実際の案件では既存のデータベースに接続するなど
SQL Server以外に接続することも多いと思われます。

そこでASP.NET MVCからSQL Server以外のデータベースに接続する実例を
作ってみました。

以下、実例を作る際のポイントです。
・データベースはOracle 10g Express Editionを使用。
・データの取得にはOracleDataReaderを使用して、Select文を発行する。
 →Select文ならほとんどのデータベースに対して実行可能であるため、汎用性が高いため。
Oracleに接続するソースについては、Microsoft .NET Pet Shop 4.0よりOracleHelperクラスを持ってくる。
→Dispose()の呼び忘れなどを考えると、OracleHelperクラスを流用するのは魅力的であるため。

では、作成した実例の重要と思われる箇所を載せていきます。
従業員に関するデータを取得して画面に表示するアプリです。
まずはControllerから。

◆EmployeesController.cs


10: namespace MvcApp.Controllers
11: {
12: public class EmployeesController : Controller
13: {
14: //
15: // GET: /Employees/
16:
17: public ActionResult Index()
18: {
19: IList employeesList = new EmployeesData().GetEmployees();
20:
21: return View(employeesList);
22: }
19行目でデータを取得し、21行目でViewオブジェクトに取得したデータを格納して返却しています。
取得したデータは一件毎に EmployeeInfoクラスに入っており、複数件のデータをIListを使用してコレクションにしています。
このEmployeeInfoクラスは、データを格納するための普通のクラスです。
(JavaでいうPlain Old Java Objectのようなもの。)

◆EmployeeInfo.cs


8: public class EmployeeInfo
9: {
10: private int _ID = 0;
11: private string _firstName = string.Empty;
12: private string _lastName = string.Empty;
13: private string _departmentName = string.Empty;
14:
15: public EmployeeInfo(int id,
16: string firstName,
17: string lastName,
18: string departmentName)
19: {
20: _ID = id;
21: _firstName = firstName;
22: _lastName = lastName;
23: _departmentName = departmentName;
24: }
25:
26: public int ID
27: {
28: get { return _ID; }
29: }
30:
31: public string FirstName
32: {
33: get { return _firstName; }
34: }
35:
36: public string LastName
37: {
38: get { return _lastName; }
39: }
40:
41: public string DepartmentName
42: {
43: get { return _departmentName; }
44: }
45: }
Controllerのポイントは取得するデータの型で、普通のクラスであるEmployeeInfoをコレクションにした
IList をViewにそのまま渡せることです。
普通のクラスをViewに渡せることで、プログラムの自由度が高くなります。

次にDataAccessです。
先に書いたように、Select文を発行しています。
◆EmployeesData.cs

12: public class EmployeesData
13: {
14: public IList GetEmployees()
15: {
16: System.Text.StringBuilder sql = new System.Text.StringBuilder();
17: sql.Append("SELECT ");
18: sql.Append(" EMPLOYEES.EMPLOYEE_ID, ");
19: sql.Append(" EMPLOYEES.FIRST_NAME, ");
20: sql.Append(" EMPLOYEES.LAST_NAME, ");
21: sql.Append(" DEPARTMENTS.DEPARTMENT_NAME ");
22: sql.Append("FROM ");
23: sql.Append(" HR.EMPLOYEES ");
24: sql.Append("INNER JOIN ");
25: sql.Append(" HR.DEPARTMENTS ");
26: sql.Append("ON ");
27: sql.Append(" EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID ");
28: sql.Append("ORDER BY ");
29: sql.Append(" EMPLOYEE_ID ");
30:
31: IList employeesList = new List();
32:
33: using (OracleDataReader rdr =
OracleHelper.ExecuteReader(OracleHelper.ConnectionStringLocalTransaction,
CommandType.Text,
sql.ToString(),
null))
34: {
35: while (rdr.Read())
36: {
37: MvcApp.Models.EmployeeInfo employee =
new MvcApp.Models.EmployeeInfo(rdr.GetInt32(0),
rdr.GetString(1),
rdr.GetString(2),
rdr.GetString(3));
38: employeesList.Add(employee);
39: }
40: }
41:
42: return employeesList;
43: }
44: }

Employees表とDepartments表を結合してデータを取得するSQL文を発行しています。
33行目でOracleHelperクラスのExecuteReader()メソッドを呼び出し、データを取得しています。
35行目〜40行目で、取得したデータを一件ずつEmployeeInfoに格納し、それをコレクションに追加しています。

最後にViewです。
◆Index.aspx


1: <%@ Page Language="C#"
Inherits="System.Web.Mvc.ViewPage<IList<MvcApp.Models.EmployeeInfo>>" %>
2:
3: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4:
5: <html xmlns="http://www.w3.org/1999/xhtml" >
6: <head runat="server">
7: <title>Index</title>
8: </head>
9: <body>
10: <table border="1">
11: <tr>
12: <th>
13: EMPLOYEE_ID
14: </th>
15: <th>
16: FIRST_NAME
17: </th>
18: <th>
19: LAST_NAME
20: </th>
21: <th>
22: DEPARTMENT_NAME
23: </th>
24: </tr>
25: <% foreach (var item in Model) { %>
26: <tr>
27: <td>
28: <%= Html.Encode(item.ID.ToString()) %>
29: </td>
30: <td>
31: <%= Html.Encode(item.FirstName) %>
32: </td>
33: <td>
34: <%= Html.Encode(item.LastName) %>
35: </td>
36: <td>
37: <%= Html.Encode(item.DepartmentName) %>
38: </td>
39: </tr>
40: <% } %>
41: </table>
42: </body>
43: </html>
Viewのポイントは、普通のクラスであるEmployeeInfoをそのまま表示していることです。
1行目にEmployeeInfoを表示するための定義があります。

この行はControllerよりViewを作成する時に
1.「Create a strongly-typed view」にチェックを入れる
2.「View data class」にIListを入力する
3.「View content」は「List」を選択する
ことで自動的に出力されます。

28行目〜37行目でEmployeeInfoのプロパティを参照していますが、
1行目の定義があることによってIntelliSense機能で入力補完をしてくれます。


今回のまとめ
1.ViewはADO.NET Entity Data Modelのオブジェクト以外にも、普通のクラスを受け取って表示できる。
2.従来どおりのSQL文を発行し、取得したデータを画面に表示することもできる。
3.上記1.2.のようにASP.NET MVCフレームワークは環境に依存しない汎用的な仕組みも使える。