原文出处:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-model

EntityFramework(简称EF),支持Code First开发方法。三种开发方法数据库优先(Database First)、模型优先(Model First)、代码优先(Code First)。Code First,首先创建模型对象的类,然后相应的数据库就可以通过ORM工具自动生成,这是一种非常迅速和干净的开发流程。

我们将构建一个电影网站,如下图。

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

一、添加模型

1.新建一个默认的ASP.NET MVC 4 网站,名称为MvcMovie。

2.右击Models文件夹,添加类Movie.cs

public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}

我们将用Movie类代表数据库中的movies信息,Movie类中的每一个属性对应数据库表中的一个字段,Movie对象的实例将会对应数据库表的一行。
3.在Models文件夹中添加MovieDBContext类

public class MovieDBContext : DbContext
{
public DbSet<Movie> Movies { get; set; }
}

MovieDBContext类代表EF movie数据库上下文,它处理在数据库中读写更新Movie类实例。DbContext类由EF提供,需要引用语句

using System.Data.Entity;

4.创建数据库连接
    打开应用程序根目录下的Web.config文件,不是视图文件夹中的那个哟。在<connectionStrings>元素中,添加连接字符串。

<add name="MovieDBContext"
connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Movies.mdf;Integrated Security=True"
providerName="System.Data.SqlClient"
/>

 二、添加控制器

1.右击Controllers文件夹,创建Movies控制器。

如果选项没有出现,请先编译应用程序。

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

VS创建了MoviesController.cs、Views文件夹下面的Movies文件夹(包含Create.cshtml、Delete.cshtml、Details.cshtml、Edit.cshtml、Index.cshtml)。

ASP.NET MVC 4 自动生成了CRUD(create、read、update、delete)方法和视图,这些代码称作脚手架代码(scaffolding),现在可以进行CRUD的操作了。

2.运行程序

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

试着操作Edit、Details和Delete功能。

3.了解自动生成的代码

public class MoviesController : Controller
{
private MovieDBContext db = new MovieDBContext(); //
// GET: /Movies/ public ActionResult Index()
{
return View(db.Movies.ToList());
}

你可以使用movie database context来查询、编辑、删除电影。db.Movies.ToList()获取Movies数据表中的所有记录,return View(db.Movies.ToList()),将结果返回给Index视图。

4.强类型模型和@model关键字

我们在之前的学习中,已经使用过将数据通过ViewBag传递给视图。ViewBag是一个动态对象,它提供了方便的后期绑定(late-bound)方法,将信息传递到视图。

ASP.NET MVC提供了传递强类型数据或对象到视图的方法。这个强类型方法允许编译时,检查代码和更好的Visual studio智能感知编辑工具。在我们的例子中,脚手架样例代码使用这种方法,创建Movies控制器和视图。

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

例如在Movies控制器中的Details代码如上图,如果Movie找到,Movie的实例就被传递到Details视图。  通过在视图顶部的@model语句,可以知道该视图需要的数据对象。

@model MvcMovie.Models.Movie

相同的还有Index()动作和视图。

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

@model IEnumerable<MvcMovie.Models.Movie> 

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

5.理解Edit方法和视图

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

Edit超链接是由Html.ActionLink方法生成的,在Views\Movies\Index.cshtml视图中。

@Html.ActionLink("Edit", "Edit", new { id=item.ID }) 

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

Html.ActionLink方法可以动态产生指向某个控制器动作的HTML超链接。其中第一个参数是超链接文本(比如,<a>Edit Me</a>),第二个参数是动作名字,最后一个是匿名对象,用来生成路由数据(比如,Id为4)。上图的超链接是http://localhost:xxxx/Movies/Edit/4

默认的路由创建在App_Start\RouteConfig.cs文件中,使用{controller}/{action}/{id}模式。

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index",
id = UrlParameter.Optional }
);
}

你也可以自己在浏览器的地址栏里面输入查询字符串,比如http://localhost:xxxx/Movies/Edit?ID=4

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

打开Movies控制器,可以看到有两个Edit动作。 尝试分析下代码。

//
// GET: /Movies/Edit/5 public ActionResult Edit(int id = )
{
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
} //
// POST: /Movies/Edit/5 [HttpPost]
public ActionResult Edit(Movie movie)
{
if (ModelState.IsValid)
{
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}

Edit视图代码如下。

@model MvcMovie.Models.Movie

@{
ViewBag.Title = "Edit";
} <h2>Edit</h2> @using (Html.BeginForm()) {
@Html.ValidationSummary(true) <fieldset>
<legend>Movie</legend> @Html.HiddenFor(model => model.ID) <div class="editor-label">
@Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Title)
@Html.ValidationMessageFor(model => model.Title)
</div> <div class="editor-label">
@Html.LabelFor(model => model.ReleaseDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ReleaseDate)
@Html.ValidationMessageFor(model => model.ReleaseDate)
</div> <div class="editor-label">
@Html.LabelFor(model => model.Genre)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Genre)
@Html.ValidationMessageFor(model => model.Genre)
</div> <div class="editor-label">
@Html.LabelFor(model => model.Price)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Price)
@Html.ValidationMessageFor(model => model.Price)
</div> <p>
<input type="submit" value="Save" />
</p>
</fieldset>
} <div>
@Html.ActionLink("Back to List", "Index")
</div> @section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

运行程序,打开/Movies网址,点击Edit,跳转至Edit视图,查看HTML代码如下。

<form action="/Movies/Edit/4" method="post">    <fieldset>
<legend>Movie</legend> <input data-val="true" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="ID" name="ID" type="hidden" value="" /> <div class="editor-label">
<label for="Title">Title</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="Title" name="Title" type="text" value="Rio Bravo" />
<span class="field-validation-valid" data-valmsg-for="Title" data-valmsg-replace="true"></span>
</div> <div class="editor-label">
<label for="ReleaseDate">ReleaseDate</label>
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-date="The field ReleaseDate must be a date." data-val-required="The ReleaseDate field is required." id="ReleaseDate" name="ReleaseDate" type="text" value="4/15/1959 12:00:00 AM" />
<span class="field-validation-valid" data-valmsg-for="ReleaseDate" data-valmsg-replace="true"></span>
</div> <div class="editor-label">
<label for="Genre">Genre</label>
</div>
<div class="editor-field">
<input class="text-box single-line" id="Genre" name="Genre" type="text" value="Western" />
<span class="field-validation-valid" data-valmsg-for="Genre" data-valmsg-replace="true"></span>
</div> <div class="editor-label">
<label for="Price">Price</label>
</div>
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" type="text" value="2.99" />
<span class="field-validation-valid" data-valmsg-for="Price" data-valmsg-replace="true"></span>
</div> <p>
<input type="submit" value="Save" />
</p>
</fieldset>
</form>

演练2-4:CodeFirst实例之“电影网站制作”-LMLPHP

5.学习Details和Delete动作代码

打开Movies控制器,查看Details动作代码。

public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
}

查看Delete和DeleteConfirmed动作。

// GET: /Movies/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Movie movie = db.Movies.Find(id);
if (movie == null)
{
return HttpNotFound();
}
return View(movie);
} // POST: /Movies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Movie movie = db.Movies.Find(id);
db.Movies.Remove(movie);
db.SaveChanges();
return RedirectToAction("Index");
}

这里HttpGet Delete动作并不是要删除某个电影,它返回了一个视图,可以提交HttpPost删除请求。直接执行HttpPost请求容易导致安全漏洞。

因为HttpPost Delete函数签名和HttpGet一样,所以使用了如下的处理。

// GET: /Movies/Delete/5
public ActionResult Delete(int? id) //
// POST: /Movies/Delete/5
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
04-21 03:46
查看更多