使用 LINQ to SQL 建立模型類別 (C#)
由 Microsoft 提供
本教學課程的目標是說明一種針對 ASP.NET MVC 應用程式建立模型類別的方法。 在本教學課程中,您會了解如何利用 MICROSOFT LINQ to SQL 建置模型類別,並執行資料庫存取。
本教學課程的目標是說明一種針對 ASP.NET MVC 應用程式建立模型類別的方法。 在本教學課程中,您會了解如何利用 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 Database 範本,將名稱指定為 MoviesDB.mdf,然後按一下 [新增] 按鈕 (參見圖 1)。
圖 01:新增 SQL Server 資料庫 (按一下以檢視完全尺寸影像)
建立新資料庫後,請在 App_Data 資料夾中按兩下 MoviesDB.mdf 檔案,即可開啓資料庫。 按兩下 [MoviesDB.mdf] 檔案可開啟 [伺服器總管] 視窗 (參見圖 2)。
當使用 Visual Web Developer 時,[伺服器總管] 視窗的名稱為 [資料庫總管] 視窗。
圖 02:使用 [伺服器總管] 視窗 (按兩下以檢視全尺寸影像)
我們需要將一個資料表新增至代表電影的資料庫。 以右鍵按一下 [資料表] 資料夾,然後選擇功能表選項 [新增資料表]。 選取此功能表選項會開啟資料表設計工具 (參見圖 3)。
圖 03:資料表設計工具 (按一下以檢視全尺寸影像)
我們需要將下列資料行新增至資料庫資料表:
資料行名稱 | 資料類型 | 允許 Null |
---|---|---|
Id | int | False |
標題 | Nvarchar(200) | False |
主管 | Nvarchar(50) | False |
您必須對 Id 資料行執行兩個特殊動作。 首先,您必須選取資料表設計工具中的資料行,然後按一下索引鍵的圖示,將 Id 資料行標示為主索引鍵資料行。 LINQ to SQL 需要您在對資料庫執行插入或更新時指定主索引鍵資料行。
接著,您必須透過將 [是] 值指派給 Is Identity 屬性,將 Id 資料行標示為 Identity 資料行 (參見圖 3)。 Identity 資料行是一個資料行,每當您將新資料列加入至資料表時,就會自動指派新的數字。
建立 LINQ to SQL 類別
我們的 MVC 模型將包含代表 tblMovie 資料庫資料表的 LINQ to SQL 類別。 建立這些 LINQ to SQL 類別最簡單的方法是,以滑鼠右鍵按一下 [模型] 資料夾,選取 [新增、新項目]、選取 LINQ to SQL 類別範本、為類別命名 Movie.dbml,然後按一下 [新增] 按鈕 (參見圖 4)。
圖 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 類別。 我們會在 MVC 檢視表中顯示 tblMovies 資料庫資料表的電影清單。
首先,我們需要修改 HomeController 類別。 您可以在應用程式的 [控制器] 資料夾中找到這個類別。 修改類別,使其看起來像清單 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
屬性所代表的所有項目。 每個 movie
都會顯示 Title
屬性的值。
請注意,ViewData.Model
屬性的值會轉換成 IEnumerable
。 這是必要的,如此才能以迴圈方式查看 ViewData.Model
的內容。 此處的另一個選項是建立強型別的view
。 當您建立強型別的 view
時,會將 ViewData.Model
屬性轉換成檢視表程式碼後置類別中的特定類型。
如果您在修改 HomeController
類別和 [索引] 檢視表之後執行應用程式,則會取得空白頁面。 您會取得空白頁面,因為 tblMovies
資料庫資料表中沒有電影記錄。
若要將記錄新增至 tblMovies
資料庫資料表,請以滑鼠右鍵按一下 [伺服器總管] 視窗中的 tblMovies
資料庫資料表 (Visual Web Developer 中的 [資料庫總管] 視窗),然後選取 [顯示資料表資料] 功能表選項。 您可以使用出現的方格來插入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()
的單一方法。
清單 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
類別具有兩個建構函式。 第一個建構函式是無參數建構函式,會在應用程式執行時被呼叫。 此建構函式會建立 MovieRepository
類別的執行個體,並將該執行個體傳遞給第二個建構函式。
第二個建構函式具有單一參數:IMovieRepository
參數。 此建構函式只會將參數的值指派給名為_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 應用程式中顯示資料庫資料的策略。 首先,我們建立 LINQ to SQL 類別,並直接在控制器動作內使用類別。 在控制器內使用 LINQ to SQL 類別,這可讓您快速且輕鬆地在 MVC 應用程式中顯示資料庫資料。
接著,我們探索稍微困難一些,卻絕對更良性之用來顯示資料庫資料的路徑。 我們利用存放庫模式,並將所有資料庫存取邏輯放在個別的存放庫類別中。 在我們的控制器中,我們是針對介面而不是具體類別來撰寫所有程式碼。 存放庫模式的優點是,可以讓我們在未來輕鬆變更資料庫存取技術,並可讓您輕鬆測試控制器類別。