目录
- 1.仓储模式在MVC应用程序中的使用
- 2.泛型仓储模式在MVC应用程序中的使用
- 3.MVC Code-First和仓储模式的应用
- 4.待续....
这篇文章中,我会解释仓储模式在MVC程序中的使用。
首先,我们需要理解什么是仓储模式【repository Pattern】,来看看下面的图片
没有使用仓储模式的MVC应用程序:
使用了仓储模式的MVC应用程序:
仓储模式,是一个抽象层,它将数据库的访问逻辑,映射到实体的访问逻辑。
下面,我们来看做一个应用程序,来体验一下仓储模式吧。
首先,打开VS2013,找到--“文件”--->>"新建"---->>"项目"
选择“ASp.NET Web 应用程序”,输入名称,选择项目存放的位置,点击”确定“按钮
在弹出来的对话框中,选择“MVC”模板,然后点击“更改身份验证”,选择“无身份验证”,点击“确定”。
接下来就生成了项目模板:
好了,第一阶段的工作就完成了。新建一个MVC程序。
现在开始第二阶段的任务:
这篇文章中,我打算使用EF Model First来完成。
首先,我来新建一个数据库,还有数据表,打开SQL 2008
这样就创建好了数据库和数据表,
USE master GO IF EXISTS (SELECT * FROM sysdatabases WHERE name=‘EmployeeManagementDB‘) DROP DATABASE EmployeeManagementDB GO CREATE DATABASE EmployeeManagementDB GO USE EmployeeManagementDB GO IF EXISTS(SELECT * FROM sysobjects WHERE name=‘Employee‘) DROP TABLE Employee GO CREATE TABLE Employee ( ID INT NOT NULL PRIMARY KEY IDENTITY(1,1), Name NVARCHAR(50) NOT NULL, Age INT NOT NULL, Email NVARCHAR(200) NOT NULL )
SQL脚本
现在就开始下面的步骤吧,右键点击项目,选择添加-->新建项
在演出来的对话框中,选择Visual C#-->ADO.NET实体数据模型-->输入名称--->添加
然后在弹出开的对话框中,选择第一个-->>>”来自数据库的EF设计器“,点击下一步:
在弹出来的对话框中,选择--“新建连接”,然后点击下一步
在出来的对画框中,输入信息,连接上我们刚才创建的数据库。测试通过之后,点击确定。
好了,截图截的差不多了,现在在我们项目中添加一个文件夹DAL,然后在往这个文件夹中,添加一个接口-->>>IEmployeeRepository.cs.
现在就是Coding了,接口中的代码是:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace RepositoryPatternMVCWithEntityFramework.DAL { interface IEmployeeRepository<T> where T:class { /// <summary> /// 获取所有的Employee /// </summary> /// <returns></returns> IEnumerable<T> GetAllEmployee(); /// <summary> /// 根据ID获取 /// </summary> /// <param name="id"></param> /// <returns></returns> T GetEmployeeById(object id); /// <summary> /// 增加 /// </summary> /// <param name="obj"></param> void InsertEmployee(T obj); /// <summary> /// 更新 /// </summary> /// <param name="obj"></param> void UpdateEmployee(T obj); /// <summary> /// 删除 /// </summary> /// <param name="id"></param> void DeleteEmployee(object id); /// <summary> /// 保存 /// </summary> void Save(); void Dispose(); } }
然后在DAL文件夹下,在添加一个类EmployeeRepository ,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace RepositoryPatternMVCWithEntityFramework.DAL { public class EmployeeRepository:IEmployeeRepository<Employee>,IDisposable { private EmployeeManagementDBEntities context; public EmployeeRepository(EmployeeManagementDBEntities context) { this.context = context; } public IEnumerable<Employee> GetAllEmployee() { return context.Employees.ToList(); } public Employee GetEmployeeById(object id) { return context.Employees.Find(id); } public void InsertEmployee(Employee obj) { context.Employees.Add(obj); } public void UpdateEmployee(Employee obj) { context.Entry(obj).State = System.Data.EntityState.Modified; } public void DeleteEmployee(object id) { Employee em= context.Employees.Find(id); context.Employees.Remove(em); } public void Save() { context.SaveChanges(); } private bool disposed = false; protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { context.Dispose(); } } this.disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } } }
然后,在控制器文件夹下,添加一个控制器EmployController,空的。。
然后,先暂停一下,我这边打算使用分页,引用pageList.mvc
现在控制器的代码:
using RepositoryPatternMVCWithEntityFramework.DAL; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; //分页引用 using PagedList; namespace RepositoryPatternMVCWithEntityFramework.Controllers { public class EmployeeController : Controller { private IEmployeeRepository<Employee> employeeRepository; public EmployeeController() { this.employeeRepository = new EmployeeRepository(new EmployeeManagementDBEntities()); } // GET: Employee public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page) { ViewBag.CurrentSort = sortOrder; ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "ID" : ""; if (searchString != null) { page = 1; } else { searchString = currentFilter; } ViewBag.CurrentFilter = searchString; var employees = from s in employeeRepository.GetAllEmployee() select s; if (!String.IsNullOrEmpty(searchString)) { employees = employees.Where(s => s.Name.ToUpper().Contains(searchString.ToUpper()) || s.Name.ToUpper().Contains(searchString.ToUpper())); } switch (sortOrder) { case "ID": employees = employees.OrderByDescending(s => s.ID); break; case "Name": employees = employees.OrderBy(s => s.Name); break; case "Email": employees = employees.OrderBy(s => s.Email); break; case "Age": employees = employees.OrderBy(s => s.Age); break; default: employees = employees.OrderBy(s => s.ID); break; } int pageSize = 5; int pageNumber = (page ?? 1); return View(employees.ToPagedList(pageNumber, pageSize)); } // GET: /Employee/Details/5 public ViewResult Details(int id) { Employee emp = employeeRepository.GetEmployeeById(id); return View(emp); } // GET: /Employee/Create public ActionResult Create() { return View(); } // POST: /Employee/Create [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create( [Bind(Include = "Name, Email")] Employee emp) { try { if (ModelState.IsValid) { employeeRepository.InsertEmployee(emp); employeeRepository.Save(); return RedirectToAction("Index"); } } catch (Exception ex) { ModelState.AddModelError(string.Empty, "Some Error Occured."); } return View(emp); } // GET: /Employee/Edit/5 public ActionResult Edit(int id) { Employee emp = employeeRepository.GetEmployeeById(id); return View(emp); } // POST: /Employee/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit(Employee emp) { try { if (ModelState.IsValid) { employeeRepository.UpdateEmployee(emp); employeeRepository.Save(); return RedirectToAction("Index"); } } catch (Exception ex) { ModelState.AddModelError(string.Empty, "Some error Occured."); } return View(emp); } // GET: /employee/Delete/5 public ActionResult Delete(bool? saveChangesError = false, int id = 0) { if (saveChangesError.GetValueOrDefault()) { ViewBag.ErrorMessage = "Some Error Occured."; } Employee emp = employeeRepository.GetEmployeeById(id); return View(emp); } // POST: /Employee/Delete/5 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Delete(int id) { try { Employee emp = employeeRepository.GetEmployeeById(id); employeeRepository.DeleteEmployee(id); employeeRepository.Save(); } catch (Exception ex) { return RedirectToAction("Delete", new { id = id, saveChangesError = true }); } return RedirectToAction("Index"); } protected override void Dispose(bool disposing) { employeeRepository.Dispose(); base.Dispose(disposing); } } }
Index视图:
@using PagedList.Mvc; @model PagedList.IPagedList<Employee> @*分页CSS*@ <link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" /> 备注一下,这个是添加pagedList分页之后,自动添加进来的。 @{ ViewBag.Title = "Employee Management System"; } <h2>Employee Management System</h2> @using (Html.BeginForm("Index", "Employee", FormMethod.Get)) { <p style="background-color:red; color:white; font-size:16pt; padding:10px;"> Search Employee By Name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string) <input type="submit" value="Search" /> @Html.ActionLink("Add New Employee", "Create") </p> } <table style="background-color:white;"> <tr> <th></th> <th style="width: 100px;"> @Html.ActionLink("Emp ID", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter }) </th> <th> @Html.ActionLink("Name", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter }) </th> <th> Email </th> <th> Age </th> <th style="width: 150px;"></th> </tr> @foreach (var item in Model) { <tr> <td></td> <td> @Html.DisplayFor(modelItem => item.ID) </td> <td style="width:130px;"> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Email) </td> <td style="width:140px;"> @Html.DisplayFor(modelItem => item.Age) </td> <td style="width:270px;"> @Html.ActionLink("Edit", "Edit", new { id = item.ID }) | @Html.ActionLink("Details", "Details", new { id = item.ID }) | @Html.ActionLink("Delete", "Delete", new { id = item.ID }) </td> </tr> } </table> <br /> <div style="background-color:orange; padding-left:15px; padding-top:10px;"> Showing Records @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount //备注一下:这里的Pagecount ,PageNumber也都是///分页控件中的 @Html.PagedListPager(Model, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter })) </div>
Create视图:
@model Employee <script src="~/Scripts/jquery-1.7.1.min.js"></script> <script src="~/Scripts/jquery.validate.min.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script> @using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.ValidationSummary(true) <fieldset> <legend>Employee</legend> <div class="editor-label"> @Html.LabelFor(model => model.Name) </div> <div class="editor-field"> @Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name) </div> <div class="editor-label"> @Html.LabelFor(model => model.Email) </div> <div class="editor-field"> @Html.EditorFor(model => model.Email) @Html.ValidationMessageFor(model => model.Email) </div> <div class="editor-label"> @Html.LabelFor(model => model.Age) </div> <div class="editor-field"> @Html.EditorFor(model => model.Age) @Html.ValidationMessageFor(model => model.Age) </div> <p> <input type="submit" value="Create" /> </p> </fieldset> } <div> @Html.ActionLink("Back to List", "Index") </div>
Edit视图:
@model Employee <script src="~/Scripts/jquery-1.7.1.min.js"></script> <script src="~/Scripts/jquery.validate.min.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script> <h2>Edit Employee information</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.ValidationSummary(true) <table> <tr> <td>@Html.LabelFor(model => model.ID)</td> <td> @Html.EditorFor(model => model.ID, new { disabled = "disabled", @readonly = "readonly" }) @Html.ValidationMessageFor(model => model.ID) </td> </tr> <tr> <td> @Html.LabelFor(model => model.Name) </td> <td> @Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name) </td> </tr> <tr> <td>@Html.LabelFor(model => model.Email)</td> <td> @Html.EditorFor(model => model.Email) @Html.ValidationMessageFor(model => model.Email) </td> </tr> <tr> <td>@Html.LabelFor(model => model.Age)</td> <td> @Html.EditorFor(model => model.Age) @Html.ValidationMessageFor(model => model.Age) </td> </tr> <tr style="background-color: orange; padding: 25px;"> <td></td> <td> <input type="submit" value="Save" /> @Html.ActionLink("Back to List", "Index") </td> </tr> </table> }
delete视图:
@model Employee <h3>Are you sure you want to delete this?</h3> <table> <tr> <td>@Html.DisplayNameFor(model => model.ID)</td> <td>@Html.DisplayFor(model => model.ID)</td> </tr> <tr> <td>@Html.DisplayNameFor(model => model.Name)</td> <td>@Html.DisplayFor(model => model.Name)</td> </tr> <tr> <td>@Html.DisplayNameFor(model => model.Email)</td> <td>@Html.DisplayFor(model => model.Email)</td> </tr> <tr> <td>@Html.DisplayNameFor(model => model.Age)</td> <td>@Html.DisplayFor(model => model.Age)</td> </tr> </table> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <table> <tr style="background-color: orange; padding: 25px;"> <td></td> <td> <input type="submit" value="Delete" /> @Html.ActionLink("Back to List", "Index") </td> </tr> </table> }
Details视图:
@model Employee <h2>Employee Details</h2> <table> <tr> <td>@Html.DisplayNameFor(model => model.ID)</td> <td>@Html.DisplayFor(model => model.ID)</td> </tr> <tr> <td>@Html.DisplayNameFor(model => model.Name)</td> <td>@Html.DisplayFor(model => model.Name)</td> </tr> <tr> <td>@Html.DisplayNameFor(model => model.Email)</td> <td>@Html.DisplayFor(model => model.Email)</td> </tr> <tr style="background-color: orange; padding: 25px;"> <td></td> <td> @Html.ActionLink("Edit", "Edit", new { id = Model.ID }) | @Html.ActionLink("Back to List", "Index") </td> </tr> </table>
效果图:
目录
- 1.仓储模式在MVC应用程序中的使用
- 2.泛型仓储模式在MVC应用程序中的使用
- 3.MVC Code-First和仓储模式的应用
- 4.待续....