LINQ to SQL を使用したモデル クラスの作成 (C#)

マイクロソフトより

PDF をダウンロードする

このチュートリアルの目的は、ASP.NET MVC アプリケーションのモデル クラスを作成する方法の 1 つについて説明することです。 このチュートリアルでは、Microsoft LINQ to SQL を利用してモデル クラスを構築し、データベース アクセスを実行する方法について説明します。

このチュートリアルの目的は、ASP.NET MVC アプリケーションのモデル クラスを作成する方法の 1 つについて説明することです。 このチュートリアルでは、Microsoft LINQ to SQL を利用してモデル クラスを構築し、データベース アクセスを実行する方法について説明します

このチュートリアルでは、基本的な Movie データベース アプリケーションを構築します。 まず、可能な限り最速かつ最も簡単な方法で Movie データベース アプリケーションを作成します。 すべてのデータ アクセスは、コントローラーアクションから直接実行します。

次に、リポジトリ パターンを使用する方法について説明します。 リポジトリ パターンを使用するには、もう少し作業が必要です。 ただし、このパターンを採用する利点は、変更に適応でき、簡単にテストできるアプリケーションを構築できることです。

モデル クラスとは

MVC モデルには、MVC ビューまたは MVC コントローラーに含まれていないすべてのアプリケーション ロジックが含まれています。 特に、MVC モデルには、すべてのアプリケーション ビジネスおよびデータ アクセス ロジックが含まれています。

さまざまなテクノロジを使用して、データ アクセス ロジックを実装できます。 たとえば、Microsoft Entity Framework、NHibernate、Subsonic、または ADO.NET クラスを使用して、データ アクセス クラスを構築できます。

このチュートリアルでは、LINQ to SQL を使用してデータベースのクエリと更新を行います。 LINQ to SQL では、Microsoft SQL Server データベースを操作する非常に簡単な方法が提供されます。 ただし、ASP.NET MVC フレームワークは LINQ to SQL に関連付けられていないことを理解しておくことが重要です。 ASP.NET MVC は、あらゆるデータ アクセス テクノロジと互換性があります。

ムービー データベースを作成する

このチュートリアルでは、モデル クラスを構築する方法を説明するために、単純な Movie データベース アプリケーションを構築します。 最初の手順では、新しいデータベースを作成します。 [ソリューション エクスプローラー] ウィンドウで App_Data フォルダーを右クリックし、メニュー オプション [追加]、[新規項目] を選択します。 SQL Server データベース テンプレートを選択し、MoviesDB.mdf名前を付けて、[追加] ボタンをクリックします (図 1 を参照)。

新しい SQL Server データベースの追加

図 01: 新しい SQL Server データベースの追加 (フルサイズの画像を表示する] をクリックします)

新しいデータベースを作成したら、App_Data フォルダー内のMoviesDB.mdf ファイルをダブルクリックしてデータベースを開くことができます。 MoviesDB.mdf ファイルをダブルクリックすると、サーバー エクスプローラー ウィンドウが開きます (図 2 を参照)。

Visual Web Developer を使用する場合、サーバー エクスプローラー ウィンドウはデータベース エクスプローラー ウィンドウと呼ばれます。

[サーバー エクスプローラー] ウィンドウのスクリーンショット。[テーブル] フォルダーがフォルダー階層で強調表示されていることを示しています。

図 02: サーバー エクスプローラー ウィンドウの使用 (フルサイズの画像を表示する] をクリックします)

ムービーを表すテーブルをデータベースに 1 つ追加する必要があります。 [テーブル] フォルダーを右クリックし、メニュー オプション [ 新しいテーブルの追加] を選択します。 このメニュー オプションを選択すると、テーブル デザイナーが開きます (図 3 を参照)。

テーブル デザイナー機能を示す Microsoft Visual Studio ウィンドウのスクリーンショット。

図 03: テーブル デザイナー (フルサイズの画像を表示する] をクリックします)

データベース テーブルに次の列を追加する必要があります。

列名 データ型 Null を許可する
ID int(整数) いいえ
タイトル Nvarchar(200) いいえ
監督 Nvarchar(50) いいえ

Id 列に対して 2 つの特別な操作を行う必要があります。 まず、テーブル デザイナーで列を選択し、キーのアイコンをクリックして、ID 列を主キー列としてマークする必要があります。 LINQ to SQL では、データベースに対して挿入または更新を実行するときに主キー列を指定する必要があります。

次に、Is Identity プロパティに値 Yes を割り当てることで、ID 列を ID 列としてマークする必要があります (図 3 を参照)。 ID 列は、新しいデータ行をテーブルに追加するたびに、自動的に新しい番号が割り当てられる列です。

LINQ to SQL クラスを作成する

MVC モデルには、tblMovie データベース テーブルを表す LINQ to SQL クラスが含まれます。 これらの LINQ to SQL クラスを作成する最も簡単な方法は、[モデル] フォルダーを右クリックし、[ 追加]、[新しい項目] の順に選択し、LINQ to SQL クラス テンプレートを選択し、クラスに Movie.dbml という名前を 付けて、[追加 ] ボタンをクリックすることです (図 4 を参照)。

LINQ to SQL クラスの作成

図 04: LINQ to SQL クラスの作成 (フルサイズの画像を表示する をクリックします)

Movie LINQ to SQL クラスを作成した直後に、オブジェクト リレーショナル デザイナーが表示されます。 サーバー エクスプローラー ウィンドウからオブジェクト リレーショナル デザイナーにデータベース テーブルをドラッグして、特定のデータベース テーブルを表す LINQ to SQL クラスを作成できます。 オブジェクト リレーショナル デザイナーに tblMovie データベース テーブルを追加する必要があります (図 5 を参照)。

オブジェクト リレーショナル デザイナーの使用

図 05: オブジェクト リレーショナル デザイナーの使用 (フルサイズの画像を表示する] をクリックします)

既定では、オブジェクト リレーショナル デザイナーは、デザイナーにドラッグするデータベース テーブルとまったく同じ名前のクラスを作成します。 ただし、クラスを tblMovie呼び出す必要はありません。 したがって、デザイナーでクラスの名前をクリックし、クラスの名前を Movie に変更します。

最後に、[ 保存 ] ボタン (フロッピーの画像) をクリックして LINQ to SQL クラスを保存します。 それ以外の場合、LINQ to SQL クラスはオブジェクト リレーショナル デザイナーによって生成されません。

コントローラー アクションでの LINQ to SQL の使用

LINQ to SQL クラスが用意されたので、これらのクラスを使用してデータベースからデータを取得できます。 このセクションでは、コントローラー アクション内で LINQ to SQL クラスを直接使用する方法について説明します。 TblMovies データベース テーブルのムービーの一覧を MVC ビューに表示します。

まず、HomeController クラスを変更する必要があります。 このクラスは、アプリケーションの Controllers フォルダーにあります。 リスト 1 のクラスのようにクラスを変更します。

リスト 1 – Controllers\HomeController.cs

using System.Linq;
using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
     [HandleError]
     public class HomeController : Controller
     {
          public ActionResult Index()
          {
               var dataContext = new MovieDataContext();
               var movies = from m in dataContext.Movies
                    select m;
               return View(movies);
          }
     }
}

リスト 1 の Index() アクションでは、LINQ to SQL DataContext クラス ( MovieDataContext) を使用して、 MoviesDB データベースを表します。 MoveDataContext クラスは、Visual Studio オブジェクト リレーショナル デザイナーによって生成されました。

LINQ クエリが DataContext に対して実行され、 tblMovies データベース テーブルからすべてのムービーが取得されます。 ムービーのリストは、 moviesという名前のローカル変数に割り当てられます。 最後に、映画の一覧がビュー データを介してビューに渡されます。

ムービーを表示するには、次にインデックス ビューを変更する必要があります。 インデックス ビューは、 Views\Home\ フォルダーにあります。 リスト 2 のビューのようにインデックス ビューを更新します。

リスト 2 – Views\Home\Index.aspx

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %>
<%@ Import Namespace="MvcApplication1.Models" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

     <ul>
          <% foreach (Movie m in (IEnumerable)ViewData.Model)

          { %>
               <li> <%= m.Title %> </li>
          <% } %>
     </ul>
</asp:Content>

変更されたインデックス ビューには、ビューの上部に <%@ import namespace %> ディレクティブが含まれていることに注意してください。 このディレクティブは、 MvcApplication1.Models namespaceをインポートします。 ビューで model クラス (特に Movie クラス) を操作するには、この名前空間が必要です。

リスト 2 のビューには、foreach プロパティによって表されるすべての項目を反復処理するViewData.Model ループが含まれています。 Title プロパティの値は、各movieに対して表示されます。

ViewData.Model プロパティの値がIEnumerableにキャストされていることに注意してください。 これは、 ViewData.Modelの内容をループ処理するために必要です。 ここでのもう 1 つのオプションは、厳密に型指定された viewを作成することです。 厳密に型指定された viewを作成すると、ビューのコードビハインドクラス内の特定の型に ViewData.Model プロパティをキャストします。

HomeController クラスとインデックス ビューを変更した後でアプリケーションを実行すると、空白のページが表示されます。 tblMovies データベース テーブルにムービー レコードがないため、空白のページが表示されます。

tblMovies データベース テーブルにレコードを追加するには、サーバー エクスプローラー ウィンドウ (Visual Web Developer の [データベース エクスプローラー] ウィンドウ) でtblMovies データベース テーブルを右クリックし、メニュー オプション [テーブル データの表示] を選択します。 表示されるグリッドを使用して、 movie レコードを挿入できます (図 6 を参照)。

ムービーの挿入

図 06: ムービーの挿入 (フルサイズの画像を表示する をクリックします)

tblMovies テーブルにいくつかのデータベース レコードを追加し、アプリケーションを実行すると、図 7 のページが表示されます。 すべてのムービー データベース レコードが箇条書きに表示されます。

インデックス ビューでムービーを表示する

図 07: インデックス ビューでムービーを表示する (フルサイズの画像を表示する をクリックします)

リポジトリ パターンの使用

前のセクションでは、コントローラー アクション内で LINQ to SQL クラスを直接使用しました。 MovieDataContext コントローラー アクションから直接、Index() クラスを使用しました。 単純なアプリケーションの場合、これを行うことに問題はありません。 ただし、コントローラー クラスで LINQ to SQL を直接操作すると、より複雑なアプリケーションを構築する必要があるときに問題が発生します。

コントローラー クラス内で LINQ to SQL を使用すると、将来的にデータ アクセス テクノロジを切り替えるのが困難になります。 たとえば、Microsoft LINQ to SQL を使用して、データ アクセス テクノロジとして Microsoft Entity Framework を使用するように切り替えることができます。 その場合は、アプリケーション内のデータベースにアクセスするすべてのコントローラーを書き換える必要があります。

コントローラー クラス内で LINQ to SQL を使用すると、アプリケーションの単体テストをビルドすることも困難になります。 通常、単体テストの実行時にデータベースと対話する必要はありません。 データベース サーバーではなく、単体テストを使用してアプリケーション ロジックをテストする必要があります。

将来の変更により適応可能で、より簡単にテストできる MVC アプリケーションを構築するには、リポジトリ パターンの使用を検討する必要があります。 リポジトリ パターンを使用する場合は、すべてのデータベース アクセス ロジックを含む個別のリポジトリ クラスを作成します。

リポジトリ クラスを作成するときは、リポジトリ クラスによって使用されるすべてのメソッドを表すインターフェイスを作成します。 コントローラー内では、リポジトリではなくインターフェイスに対してコードを記述します。 そうすることで、将来、さまざまなデータ アクセス テクノロジを使用してリポジトリを実装できます。

リスト 3 のインターフェイスは IMovieRepository という名前で、 ListAll()という名前の 1 つのメソッドを表します。

リスト 3 – Models\IMovieRepository.cs

using System.Collections.Generic;
namespace MvcApplication1.Models
{
     public interface IMovieRepository
     {
          IList<Movie> ListAll();
     }
}

リスト 4 のリポジトリ クラスは、 IMovieRepository インターフェイスを実装します。 ListAll() インターフェイスに必要なメソッドに対応する IMovieRepository という名前のメソッドが含まれていることに注意してください。

リスト 4 – Models\MovieRepository.cs

using System.Collections.Generic;
using System.Linq;

namespace MvcApplication1.Models
{
     public class MovieRepository : IMovieRepository
     {
          private MovieDataContext _dataContext;

          public MovieRepository()
          {
                _dataContext = new MovieDataContext();
          }

          #region IMovieRepository Members

          public IList<Movie> ListAll()
          {
               var movies = from m in _dataContext.Movies
                    select m;
               return movies.ToList();
          }

          #endregion
     }
}

最後に、リスト 5 の MoviesController クラスはリポジトリ パターンを使用します。 LINQ to SQL クラスを直接使用しなくなりました。

リスト 5 – Controllers\MoviesController.cs

using System.Web.Mvc;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
     public class MoviesController : Controller
     {
          private IMovieRepository _repository;

          public MoviesController() : this(new MovieRepository())
          {
          }

          public MoviesController(IMovieRepository repository)
          {
               _repository = repository;
          }

          public ActionResult Index()
          {
               return View(_repository.ListAll());
          }
     }
}

リスト 5 の MoviesController クラスには 2 つのコンストラクターがあることに注意してください。 最初のコンストラクター (パラメーターなしのコンストラクター) は、アプリケーションの実行中に呼び出されます。 このコンストラクターは、 MovieRepository クラスのインスタンスを作成し、2 番目のコンストラクターに渡します。

2 番目のコンストラクターには、 IMovieRepository パラメーターという 1 つのパラメーターがあります。 このコンストラクターは、パラメーターの値を _repository という名前のクラス レベルのフィールドに割り当てるだけです。

MoviesController クラスは、依存関係挿入パターンと呼ばれるソフトウェア設計パターンを利用しています。 特に、コンストラクタ依存性注入を使用しています。 このパターンの詳細については、Martin Fowler の次の記事を参照してください。

http://martinfowler.com/articles/injection.html

MoviesController クラスのすべてのコード (最初のコンストラクターを除く) が、実際の IMovieRepository クラスではなく、MovieRepository インターフェイスとやり取りしていることに注意してください。 コードは、インターフェイスの具体的な実装ではなく、抽象インターフェイスと対話します。

アプリケーションで使用されるデータ アクセス テクノロジを変更する場合は、代替データベース アクセス テクノロジを使用するクラスを使用して、 IMovieRepository インターフェイスを実装するだけです。 たとえば、 EntityFrameworkMovieRepository クラスまたは SubSonicMovieRepository クラスを作成できます。 コントローラー クラスはインターフェイスに対してプログラミングされるため、 IMovieRepository の新しい実装をコントローラー クラスに渡すと、クラスは引き続き動作します。

さらに、 MoviesController クラスをテストする場合は、偽のムービー リポジトリ クラスを HomeControllerに渡すことができます。 IMovieRepository クラスは、データベースに実際にはアクセスせず、IMovieRepository インターフェイスのすべての必要なメソッドを含むクラスを使用して実装できます。 こうすることで、実際のデータベースに実際にアクセスすることなく、 MoviesController クラスを単体テストできます。

まとめ

このチュートリアルの目的は、Microsoft LINQ to SQL を利用して MVC モデル クラスを作成する方法を示すことでした。 ASP.NET MVC アプリケーションでデータベース データを表示するための 2 つの戦略を調べました。 まず、LINQ to SQL クラスを作成し、コントローラー アクション内で直接クラスを使用しました。 コントローラー内で LINQ to SQL クラスを使用すると、MVC アプリケーションでデータベース データをすばやく簡単に表示できます。

次に、データベース データを表示するための、もう少し難しいが、間違いなくより好ましいパスについて説明しました。 リポジトリ パターンを利用し、すべてのデータベース アクセス ロジックを別のリポジトリ クラスに配置しました。 コントローラーでは、具象クラスではなく、インターフェイスに対してすべてのコードを記述しました。 リポジトリ パターンの利点は、将来的にデータベース アクセス テクノロジを簡単に変更でき、コントローラー クラスを簡単にテストできる点です。