Linq to SQL與.net MVC

什麼是 Model 類?

MVC 模型包含未包含在 MVC 視圖或 MVC 控制器中的所有應用程序邏輯。其特別之處在於,MVC 模型包含所有應用程序業務和數據訪問邏輯。

可以使用各種不同的技術實現數據訪問邏輯。例如,可以使用 Microsoft Entity Framework、NHibernate、Subsonic 或 ADO.NET 類構建數據訪問類。

在本教程中,作者將使用 LINQ to SQL 查詢並更新數據庫。LINQ to SQL 提供了一種非常簡單的方法來與 Microsoft SQL Server 數據庫交互。但是,我們並未將 ASP.NET MVC Framework 以任何方式附加到 LINQ to SQL,瞭解這一點非常重要。ASP.NET MVC 可以與任何數據訪問技術兼容。

創建 Movie 數據庫

在本教程中,爲了說明如何構建 Model 類,我們將構建一個簡單的 Movie 數據庫應用程序。第一步是創建新的數據庫。右鍵單擊 Solution Explorer 窗口中的 App_Data 文件夾,然後選擇菜單選項 Add,New Item。選擇 SQL Server Database模板,將其命名爲 MoviesDB.mdf,然後單擊Add 按鈕(如圖 1 所示)。

圖 1:添加新的 SQL Server 數據庫(單擊查看大圖

創建新的數據庫後,可以雙擊 App_Data 文件夾中的 MoviesDB.mdf 文件打開數據庫。雙擊 MoviesDB.mdf 文件打開 Server Explorer 窗口(如圖 2 所示)。

在使用 Visual Web Developer 時,Server Explorer 窗口稱爲 Database Explorer 窗口。

圖 2:使用 Server Explorer 窗口(單擊查看大圖

需要向數據庫添加表示電影的表。右鍵單擊 Tables 文件夾並選擇菜單選項 Add New Table。選擇此菜單選項將打開 Table Designer(如圖 3 所示)。

圖 3:Table Designer(單擊查看大圖

需要將以下列添加到數據庫表:

列名稱

數據類型

允許空值

Id

Int

False

Title

Nvarchar(200)

False

Director

Nvarchar(50)

False

需要對 Id 列進行兩項特殊的處理。首先,需要將 Id 列標記爲主鍵列,方法是在 Table Designer 中選擇列,然後單擊鑰匙圖標。LINQ to SQL 要求在執行插入或更新數據庫時指定主鍵列。

接下來,需要將 Id 列標記爲 Identity 列,方法是將 Is Identity 屬性賦值爲 Yes(如圖 3 所示)。每當將新數據行添加到表時,都會自動給 Identity 列分配一個新序號。

創建 LINQ to SQL 類

我們的 MVC 模型將包含表示 tblMovie 數據庫表的 LINQ to SQL 類。要創建這些 LINQ to SQL 類,最簡單的方法是右鍵單擊 Models 文件夾,選擇Add,New Item,選擇 LINQ to SQL Classes 模板,將類命名爲 Movie.dbml,然後單擊Add 按鈕(如圖 4 所示)。

圖 4:創建 LINQ to SQL 類(單擊查看大圖

創建 Movie LINQ to SQL 類之後,Object Relational Designer 將立即出現。可以將數據庫表從 Server Explorer 窗口拖到 Object Relational Designer 上,以創建代表特殊數據庫表的 LINQ to SQL 類。我們需要將 tblMovie 數據庫表添加到 Object Relational Designer 上(如圖 5 所示)。

圖 5:使用 Object Relational Designer(單擊查看大圖

默認情況下,Object Relational Designer 創建一個與拖放到 Designer 上的數據庫表名稱相同的類。但是,我們不希望類的名稱爲tblMovie。因此,單擊 Designer 中的類名稱並將其更改爲 Movie。

最後,要記住單擊 Save按鈕(軟盤圖標)保存 LINQ to SQL 類。否則,Object Relational Designer 將不會生成 LINQ to SQL 類。

在控制器操作中使用 LINQ to SQL

生成 LINQ to SQL 類之後,我們可以使用這些類從數據庫中檢索數據。在本部分中,我們將學習如何直接在控制器操作中使用 LINQ to SQL 類。我們將從 MVC 視圖的 tblMovies 數據庫表中顯示電影列表。

首先,我們需要修改 HomeController 類。該類位於應用程序的 Controllers 文件夾中。將該類修改爲如程序清單 1 所示。

程序清單 1Controllers\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 Object Relational Designer 生成。

對 DataContext 執行 LINQ 查詢,以便從 tblMovies 數據庫表中檢索所有電影。電影列表被分配給名稱爲 movies 的局部變量。最後,通過視圖數據將電影列表傳遞給視圖。

爲了顯示電影,需要修改 Index 視圖。Index 視圖位於 Views\Home\ 文件夾中。將 Index 視圖更新爲如程序清單 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>

請注意,修改後的 Index 視圖在開頭包含<%@ import namespace %>指令。此指令導入MvcApplication1.Models命名空間。必須具備此命名空間,才能使用視圖中的model類(即 Movie類)。

程序清單 2 中的視圖包含foreach循環,該循環遍歷所有由ViewData.Model屬性表示的項,顯示了每個movieTitle 屬性值。

請注意,ViewData.Model屬性的值被分配爲IEnumerable。爲了遍歷ViewData.Model的內容,這是必須的。此處的另一個選項是創建強類型的view。創建強類型的view時,會將ViewData.Model屬性分配爲某個視圖的代碼隱藏類中的特定類型。

如果在修改 HomeController 類和 Index 視圖後運行應用程序,則將得到空白頁面。得到空白頁面的原因是tblMovies 數據庫表中沒有電影記錄。

爲了在tblMovies數據庫表中添加一些記錄,請右鍵單擊 Server Explorer 窗口(Visual Web Developer 中的 Database Explorer 窗口)中的tblMovies數據庫表,然後選擇菜單選項 Show Table Data。使用出現的網格可以插入movie記錄(如圖 6 所示)。

圖 6:插入電影(單擊查看大圖

tblMovies表添加若干數據庫記錄後,再運行應用程序,將看到如圖 7 所示的頁面。所有電影的數據庫記錄將顯示在項目符號列表中。

圖 7:使用 Index 視圖顯示電影(單擊查看大圖

使用 Repository 模式

在前一部分中,我們直接在控制器操作中使用了 LINQ to SQL 類。我們直接從 Index()控制器操作使用了 MovieDataContext類。對於簡單的應用程序來說,這樣做沒有任何不妥之處。然而,如果需要構建更加複雜的應用程序,那麼直接在控制器類中使用 LINQ to SQL 就會出現問題。

在控制器類中使用 LINQ to SQL 使得將來切換數據訪問技術變得非常困難。例如,您可能決定不使用 Microsoft LINQ to SQL,而改爲使用 Microsoft Entity Framework 作爲數據訪問技術。在這種情況下,需要重新編寫應用程序中每個訪問數據庫的控制器。

在控制器類中使用 LINQ to SQL 還使得難以構建應用程序的單元測試。通常,在執行單元測試時不希望與數據庫交互。您希望使用單元測試來測試應用程序邏輯,而不是數據庫服務器。

爲了構建在將來更適合更改和易於測試的 MVC 應用程序,應該考慮使用 Repository 模式。在使用 Repository 模式時,會創建單獨的包含所有數據庫訪問邏輯的儲存庫類。

在創建儲存庫類時,會創建代表所有儲存庫類所使用的方法的接口。在控制器中,針對接口而不是儲存庫編寫代碼。通過這種方法,可以在將來使用不同的數據訪問技術實現儲存庫。

程序清單 3 中的接口名稱爲IMovieRepository,它代表一個名稱爲ListAll()的方法。

程序清單 3 Models\IMovieRepository.cs

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

程序清單 4 中的 Repository 類實現 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 類使用 Repository 模式。它不再直接使用 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類有兩個構造方法。在應用程序運行時調用第一個構造方法(parameterless 構造方法)。此構造方法創建MovieRepository類的一個實例,然後將其傳遞給第二個構造方法。

第二個構造方法只有一個參數:IMovieRepository參數。此構造方法只是將參數值分配給類級別的字段,其名稱爲_repository

MoviesController 類利用稱爲 Dependency Injection 的軟件設計模式。在此處,它使用的技術稱爲 Constructor Dependency Injection。請閱讀以下由 Martin Fowler 撰寫的文章,瞭解更多有關此模式的信息:

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

請注意,MoviesController類的所有代碼(除了第一個構造方法以外)與IMovieRepository接口而不是MovieRepository類交互。代碼與抽象的接口而不是具體實現的接口交互。

如果想修改應用程序使用的數據訪問技術,則可以簡單地通過使用替代數據訪問技術的類實現IMovieRepository接口。例如,可以創建一個EntityFrameworkMovieRepository類或SubSonicMovieRepository類。由於控制器類是針對接口編寫的,因此可以將IMovieRepository的新實現傳遞給控制器類,而該類將繼續工作。

更進一步,如果想測試 MoviesController類,則可以將仿造的電影儲存庫類傳遞給MoviesController。可以使用實際上不訪問數據庫,但包含所有IMovieRepository接口要求的方法的類來實現IMovieRepository類。通過這種方式,可以在不訪問實際數據庫的情況下對MoviesController類進行單元測試。

總結

本教程的目的是向讀者介紹如何利用 Microsoft LINQ to SQL 創建 MVC 模型類。我們研究了兩種在 ASP.NET MVC 應用程序中顯示數據庫數據的策略。首先,我們創建了 LINQ to SQL 類並直接在控制器操作中使用該類。在控制器中使用 LINQ to SQL 類可以輕而易舉地在 MVC 應用程序中顯示數據庫數據。

接下來,我們研究了一種稍微困難,但更加優越的顯示數據庫數據的方法。我們利用了 Repository 模式並將所有數據庫訪問邏輯放到單獨的儲存庫類中。在控制器中,我們針對接口而不是具體的類編寫所有代碼。Repository 模式的優勢在於可以在將來輕鬆地更改數據庫訪問技術和測試控制器類。


轉載msdn http://msdn.microsoft.com/zh-cn/dd408820.aspx 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章