LINQ to SQL でモデル クラスを作成する (VB)

提供元: Microsoft

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 データベースを作成する

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

Adding a new SQL Server Database

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

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

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

Screenshot of the Server Explorer window, which is showing that the Tables folder is highlighted in the folder hierarchy.

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

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

Screenshot of the Microsoft Visual Studio window, which is showing the Table Designer feature.

図 03: テーブル デザイナー (クリックするとフルサイズの画像が表示されます)

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

列名 [データ型] [NULL を許容]
Id int False
Title Nvarchar(200) False
監督 NVarchar(50) False

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

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

これらの変更を行った後、tblMovie という名前でテーブルを保存します。 [保存] ボタンをクリックすると、テーブルを保存できます。

LINQ to SQL クラスを作成する

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

Creating LINQ to SQL classes

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

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

Using the Object Relational Designer

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

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

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

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

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

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

リスト 1 – Controllers\HomeController.vb

<HandleError()> _
Public Class HomeController

     Inherits System.Web.Mvc.Controller

     Function Index()
          Dim dataContext As New MovieDataContext()
          Dim movies = From m In dataContext.Movies _
               Select m
          return View(movies)
     End Function
End Class

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

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

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

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

<%@ Page Language="VB" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.vb" Inherits="MvcApplication1.Index" %>
<%@ Import Namespace="MvcApplication1" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

<ul>
<%  For Each m As Movie In ViewData.Model%>
    <li><%= m.Title %></li>
<% Next%>
</ul>
</asp:Content>

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

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

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

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

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

Inserting movies

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

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

Displaying movies with the Index view

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

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

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

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

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

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

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

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

リスト 3 – Models\IMovieRepository.vb

Public Interface IMovieRepository
     Function ListAll() As IList(Of Movie)
End Interface

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

リスト 4 – Models\MovieRepository.vb

Public Class MovieRepository Implements IMovieRepository
         Private _dataContext As MovieDataContext

         Public Sub New()
              _dataContext = New MovieDataContext()
         End Sub

         Public Function ListAll() As IList(Of Movie) Implements IMovieRepository.ListAll
              Dim movies = From m In _dataContext.Movies _
                   Select m
              Return movies.ToList()
         End Function
End Class

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

リスト 5 – Controllers\MoviesController.vb

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

namespace MvcApplication1.Controllers
{
    Public Class MoviesController 
        Inherits System.Web.Mvc.Controller

             Private _repository As IMovieRepository

             Sub New()
                  Me.New(New MovieRepository())
             End Sub

             Sub New(ByVal repository As IMovieRepository)
                  _repository = repository
             End Sub

             Function Index()
                  Return View(_repository.ListAll())
             End Function
    End Class
}

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

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

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

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

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

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

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

まとめ

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

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