前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MVC3教程之实体模型和EF CodeFirst

MVC3教程之实体模型和EF CodeFirst

作者头像
拓荒者-NET
发布2019-09-26 11:20:11
1.3K0
发布2019-09-26 11:20:11
举报

  在本节中,我们将使用Entity Framework 数据访问技术来定义这些模型类,并对这些类来进行操作。EF支持一个被称之为“code-first”的开发范例。Code-first允许你通过书写一些简单的类来创建模型对象,而不用关心这些类的持久化。你可以通过访问这些类的方式来访问数据库,这是一种非常方便快捷的开发模式。

1.添加一个Model

  添加Model和添加普通类的操作是一样的,默认的约定是将它放在Models文件夹中。我们在Models文件夹上面点击右键,选择“添加”>“类”,在打开的对话框中输入类名“Book”,点击“添加”按钮。编辑器会为我们打开Book类,我们对这个类进行如下修改:

代码语言:javascript
复制
using System;
namespace MvcHelloworld.Models
{
    publicclass Book
    {
        publicint BookID { get; set; }
        publicstring BookName { get; set; }
        publicstring Author { get; set; }
        publicstring Publisher { get; set; }
        publicdecimal Price { get; set; }
        publicstring Remark { get; set; }
    }
}

  我们将使用这个类来表示数据库中的记录。每一个Book类的实例对应数据库中的一行,Book类中的每一个属性被映射到数据库中的一列。

2.添加数据库上下文

  在Models文件夹下新建一个名为“BookDbContext”的类,编辑这个类,将该类派生自“DbContext”类,编辑后的代码如下:

代码语言:javascript
复制
using System;
using System.Data.Entity;
namespace MvcHelloworld.Models
{
    publicclass BookDbContext : DbContext
    {
        public DbSet<Book> Books { get; set; }
    }
}

  BookDbContext代表EF中Book在数据库中的上下文对象,通过DbSet<Book>使实体类与数据库关联起来。Books属性表示数据库中的数据集实体,用来处理数据的存取与更新。BookDbContext派生自DbContext,需要添加System.Data.Entity的引用。

3.添加数据库连接

  由于我们创建的是空的Mvc项目,所以在Web.config文件中,不包含任何的数据库连接字符串,我们打开Web.config文件,为它添加一个数据库连接字符串的配置:

代码语言:javascript
复制
<connectionStrings>
    <add name="BookDbContext" connectionString=" Data Source=.\SQLEXPRESS;Initial Catalog=db_book;Persist Security Info=True;Integrated Security=SSPI;"
         providerName="System.Data.SqlClient"/>
  </connectionStrings>

  我们将数据库连接的name属性设置为“BookDbContext”,这个连接会被BookDbContext类使用,并根据连接创建相应的数据库。

4.为Book创建控制器和Index视图

  按照第一节中的步骤,我们为Book模型创建一个控制器:在文件夹“Controllers”上面点击右键 > “添加” > “控制器”,在打开的添加控制器对话框中,将控制器的名称修改为“BookController”,基架选择中的模板选择“空控制器”,如下图:

  点击“添加”按钮后,VS会添加一个BookController的文件,该文件处于打开状态。编辑Index方法的代码,查找作者为Tom的图书:

代码语言:javascript
复制
public ActionResult Index()
        {
            var books = from b in db.Books
                        where b.Author =="Tom"
                        select b;
            return View(books.ToList());
        }

  在这段代码中,db是类BookDbContext的一个实例,我们在Controller类中定义如下:BookDbContext db = new BookDbContext();

  这是一个简单的Linq查询,在对数据库进行操作时,EF会检查当前的数据连接指定的数据库是否被创建,如果没有则有EF负责根据实体模型类创建数据库、数据表;如果存在,EF会将查询条件添加到Sql查询语句,再将Sql语句发送到数据库进行数据读取。在完成数据读取后,将数据转换为实体对象集合。EF对数据库的操作大致如此。

  在Index方法内点击右键 > “添加视图”,在打开的“添加视图”对话框,勾选“创建强类型视图”,在模型类列表中选择“Book(MvcHelloworld.Models)”,在支架模板列表中选择“List”,如下图:

  点击“添加”按钮,VS为我们在Views文件夹下创建了“Book”文件夹,并在Book文件夹中添加了文件“Index.cshtml”。

  Index.cshtml是我们的视图页面,我们可以把它看做一个模板,将我们的数据按照模板的格式进行输出。在这个模板中,我们使用了Razor视图引擎,在Razor中,我们可以使用@model 用来指定传到视图的 Model 类型,访问传入视图的数据内容。我们简单的修改代码,如果你了解HTML,这将是很简单的事情:

代码语言:javascript
复制
@model IEnumerable<MvcHelloworld.Models.Book>
@{
    ViewBag.Title = "图书列表 - MvcBook";
}
<h2>图书列表</h2>
<p>
    @Html.ActionLink("增加图书", "Create")
</p>
<table>
    <tr>
        <th>
            图书名称
        </th>
        <th>
            作者
        </th>
        <th>
            出版社
        </th>
        <th>
            价格
        </th>
        <th>
            备注
        </th>
        <th></th>
    </tr>
@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.BookName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Author)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Publisher)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Price)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Remark)
        </td>
        <td>
            @Html.ActionLink("编辑", "Edit", new { id=item.BookID }) |
            @Html.ActionLink("查看", "Details", new { id=item.BookID }) |
            @Html.ActionLink("删除", "Delete", new { id=item.BookID })
        </td>
    </tr>
}
</table>

  编译并运行程序,在浏览器中输入地址:http://localhost:xxx/Book,得到的运行结果如下:

  尽管没有数据,但EF已经为我们创建了相应的数据库。

  5.增加Create视图

  “增加图书”连接需要我们有一个Create控制器和与之对应的视图。打开BookController文件,添加一个Create方法,代码如下:

代码语言:javascript
复制
public ActionResult Create()
        {
            return View();
        }

  这个方法返回一个视图,该视图中包含了用户要输入的表单。现在我们来实现这个Create视图,我们将在这个视图中向用户显示追加数据时所需要用到的表单。在Create方法中点击鼠标右键,并点击上下文菜单中的“添加视图”。在“添加视图”对话框中勾选“创建强类型视图”,在模型类列表中选择“Book(MvcHelloworld.Models)”,在支架模板列表中选择“Create”,如下图:

  点击“添加”按钮,VS会在Views/Book目录下添加一个Create.cshtml文件,由于我们选择了Create支架模板,所以在VS为我们生成了一些默认的代码。在这个视图模板中,我们指定了强类型Book作为它的模型类,VS检查Book类,并根据Book类的属性,生成了对应的标签名和编辑框,我们修改标签名,使它显示中文,修改后的代码如下:

代码语言:javascript
复制
@model MvcHelloworld.Models.Book
@{
    ViewBag.Title = "新增图书 - MvcBook";
}
<h2>新增图书</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>图书</legend>
        <div class="editor-label">
            图书名称
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.BookName)
            @Html.ValidationMessageFor(model => model.BookName)
        </div>
        <div class="editor-label">
            作者
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Author)
            @Html.ValidationMessageFor(model => model.Author)
        </div>
        <div class="editor-label">
            出版社
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Publisher)
            @Html.ValidationMessageFor(model => model.Publisher)
        </div>
        <div class="editor-label">
            价格
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Price)
            @Html.ValidationMessageFor(model => model.Price)
        </div>
        <div class="editor-label">
            备注
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Remark)
            @Html.ValidationMessageFor(model => model.Remark)
        </div>
        <p>
            <input type="submit" value="增加"/>
        </p>
    </fieldset>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

  分析这段代码:

  • @model MvcHelloworld.Models.Book:指定了该视图模板中的“模型”强类型化成一个Book类。
  • @using (Html.BeginForm()){ }:创建一个Form表单,在表单中包含了对于Book类所生成的对应字段。
  • @Html.EditorFor(model => model.BookName):根据模型生成模型中BookName的编辑控件(生成一个Input元素)
  • @Html.ValidationMessageFor(model => model.BookName):根据模型生成模型中BookName的验证信息。

  编译项目,在浏览器中输入http://localhost:xxx/Book/Create, 查看新增界面,截图如下:

6.添加Create的Postback方法

  在完成了添加Create视图后,我们仅是可以将添加界面显示出来,并不能实际的完成数据的添加,因为我们还没有增加按钮的处理方法,没有实际的处理添加事件。为了能够完成数据的增加,下面我们来添加一个Create的POSTBack方法,代码如下:

代码语言:javascript
复制
[HttpPost]
        public ActionResult Create(Book book)
        {
            if (ModelState.IsValid)
            {
                db.Books.Add(book);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            else
                return View(book);
        }

  这时,我们在页面上输入数据,并点击“增加”按钮时,EF就会通过这段代码来添加一行数据库记录。打开数据库,我们可以看到如下记录:

  7.设置实体模型的数据验证

  在ASP.NET MVC中,有一条作为核心的原则,就是DRY(“Don’t Repeat Yourself,中文意思为:不要让开发者重复做同样的事情,即“一处定义、处处可用”)原则。这样可以减少开发者的代码编写量,同时也更加便于代码的维护。

  ASP.NET MVC与EF code-first提供的默认验证规则就是一个实现DRY原则的很好的例子。你也可以在模型类中显式地追加一个验证规则,然后在整个应用程序中都使用这个验证规则。

  打开Book模型文件,添加 System.ComponentModel.DataAnnotations 的引用,并修改实体类的代码如下:

代码语言:javascript
复制
publicclass Book
    {
        publicint BookID { get; set; }
        [Required(ErrorMessage="必须输入图书名称")]
        [StringLength(maximumLength:100, MinimumLength=1, ErrorMessage="最多允许输入100个字符")]
        publicstring BookName { get; set; }
        [Required(ErrorMessage ="必须输入作者名称")]
        publicstring Author { get; set; }
        [Required(ErrorMessage ="必须输入出版社")]
        publicstring Publisher { get; set; }
        publicdecimal Price { get; set; }
        publicstring Remark { get; set; }
    }

  将数据库中之前生成的数据库db_Book删除掉,重新生成解决方案,打开新增页面,不输入任何数据的时候点击“增加”按钮,这个时侯,界面上会出现一些提示信息,并且阻止了我们进行数据的提交操作。界面如下:

  这是一个简单的验证设置,通过设置验证,EF还会在生成的数据库中添加验证信息,例如是否为空、字符串长度等,如果要了解更多EF的功能,请看我的另一篇随笔:Entity Framework 4.1 Code-First 学习笔记

  通过本节的学习,我们可以了解EF CodeFirst功能、MVC实体模型的操作等。对于实体的操作,还有更新、查看和删除操作,笔者不再一一讲解其步骤,只将控制器代码贴出,以供朋友们参照。视图的代码可以参考自动生成,稍作修改即可。

代码语言:javascript
复制
BookController代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcHelloworld.Models;
namespace MvcHelloworld.Controllers
{
    publicclass BookController : Controller
    {
        BookDbContext db =new BookDbContext();
        public ActionResult Index()
        {
            var books = from b in db.Books
                        select b;
            return View(books.ToList());
        }
        public ActionResult Create()
        {
            return View();
        }
        [HttpPost]
        public ActionResult Create(Book book)
        {
            if (ModelState.IsValid)
            {
                db.Books.Add(book);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            else
                return View(book);
        }
        public ActionResult Edit(int id)
        {
            Book book = db.Books.Find(id);
            if (book ==null)
                return RedirectToAction("Index");
            return View(book);
        }
        [HttpPost]
        public ActionResult Edit(Book newBook)
        {
            try
            {
                Book oldBook = db.Books.Find(newBook.BookID);
                UpdateModel(oldBook);
                db.SaveChanges();
                return RedirectToAction("Details", new { id = newBook.BookID });
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("", "修改失败,请查看详细错误信息:"+ ex.Message); 
            }
            return View(newBook);
        }
        public ActionResult Details(int id)
        {
            Book book = db.Books.Find(id);
            if (book ==null)
                return RedirectToAction("Index");
            return View(book);
        }
        public ActionResult Delete(int id)
        {
            Book book = db.Books.Find(id);
            if (book ==null)
                return RedirectToAction("Index");
            return View(book);
        }
        [HttpPost]
        public ActionResult Delete(int id, FormCollection collection)
        {
            Book book = db.Books.Find(id);
            db.Books.Remove(book);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2011-07-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档