asp.net mvc(参考asp.net开发指南)

什么是Model

Model可翻译为“模型”,笔者认为译成“数据模型”会更贴切一些,因为Model负责所有与“数据”相关的任务,大致如下:

定义数据结构

负责与数据库沟通

从数据库中读取数据

将数据写入数据库

运行运储程序

数据格式验证

定义与验证商业逻辑视图

对数据进行各种加工处理。例如:指定特定实体(Entity)某些字段的默认值。

以.NET或Java平台开发经验来说,你可以想象Model是一个命名空间(Namespace或Package),定义了一堆Type或Class来负责所有跟数据相关的工作。常见的相关技术包括ADO.NET,强类别数据集(Typed DataSet)、Entity Framework、LINQ to SQL、LINQ to SQL partial method、数据访问层(Data Access Layer)、Repository Pattern。

什么是控制器

 

Controller可翻译为“控制器”,顾名思义是“掌控全局的对象”,其负责的工作如下:

 

决定与“用户”沟通的管道,以ASP.NET MVC为例就是HTTP或HTTPS.

决定系统运作的“流程”。例如,从Controller接收到数据后要立刻转向

(Redirect)到另一个页面。

负责从Model取得数据,我们可以在Cotroller的类别中利用Model提供的类别来取得数据。

决定应该显示哪个View,一个网站里有很多呈现的View,要挑选哪一个View来呈现给用户,是Controller的责任。或是当Controller运行的过程中发生异常时,也可由Cotroller挑选适当的View进行响应。

 

什么是View?

View负责呈现在用户面前的东西,最简单的说法就是输出与输入,输出工作就是呈现在浏览器上的界面,例如:输出HTML、XML,等等。输入工作则是将用户输入的数据传回服务器,例如,在浏览器上呈现网页窗体让用户输入。

以下,简单地介绍在View中与输出/输入有关的工作。

输出

从Controller取得数据,并显示在用户界面上。

决定要用什么技术来呈现“用户界面”(例如,HTML,XML,Silverlight,flash,等)

负责界面的排版、字型、颜色、美观与各种呈现方式。

将Controller传送的数据显示于界面,而数据是参考自Model的定义。

参考Model的数据格式定义数据显示。

输入

负责将数据送回Controller

HTML窗体通过GET或POST输出数据。

决定数据应该送到哪一个Controller的Action中。

决定数据传送的方式,例如:GET、POST、XML HTTP Request(XHR)。

前端基本的数据格式验证。

验证功能,例如,使用JavaScript验证表单域是否输入。

参考Model的类别定义,在Visual Studio中利用Intellisense撰写程序。

1.利用aspNet mvc 4项目模板创建项目

开启visual studio2012,选择“文件”->“项目”菜单命令。

在打开的“新建项目”对话框中展开Web->ASP.NET MVC4 Web应用程序”,在“名称”文本框中输入“MvcGuestbook”,如图1所示

 

                               图1

新增项目时,会先弹出项目模板选择精灵,询问你要使用哪个项目模板。在此我们选择“Internet应用程序”,而其他选项保留其默认即可,最后单击“确定”按钮,如图2所示

 

                               图2

运行“调试”->“启动调试”(或按下F5键)命令运行网站,即可启动一个默认的ASP.NET MVC4网站。

   此网站具有非常基本的功能,如图3所示,包括3页简单的页面与会员机制,这些页面都套用主板页面(Layout Page),使用ASP.NET内建的Membership功能,可以进行会员注册,登录,注销等。

 

                                   图3  运行默认的ASP.NET MVC4网站

ASP.NET MVC4项目新增完成后,会自动创建几个标准的目录结构与重要文档。如图4所示是默认项目模板所创建的重要文档。

 

       图4

其文档解释为:其中app_startBundleConfig.cs定义css/JS打包的规则,FilterConfig.cs为全局Action Filter定义的地方,RouteConfig为定义路由(Routing)的地方。

Content放置网站内所有静态属性,例如:图片,CSS,下载文件,影片...

Controllers防止ASP.NET MVC控制器。

Models放置所有ASP.NET MVCModels有关的程序代码,例如,EDMXDBML...

Scripts放置所有JavaScriptVBScript脚本文件存放地址

Views放置ASP.NET MVC检视

Shared放置全站共享检视的目录,可能防止Layout页面或Partial View或自定义默认错误页面等。

ASP.NET MVC若要通过“网址路径”来查找文档,就必须配合ASP.NET MVC架构的规范来查找文档,事实上ASP.NET MVC的“网址路径”与“文档路径”的对应关系是通过“网址路由”来定义的,我们可以从项目内的APP_Start\RouteConfig.cs文档看到一个RegisterRoutes方法,定义如下:

 

        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 }

);

这里定义了两个默认的网址路由(Routing)。

IgnoreRoute:设置*.asd等格式的网址路径不要通过ASP.NET MVC运行。例如:ASP.NET内建的Trace.axd或其他默认的HttpHandler都不要通过ASP.NET MVC处理,这样设置的目的是让ASP.NET MVC与ASP.NET Web Form可以在同一平台下运行而不会互相影响。

MapRoute:通过MaoRoute方法是定义ASP.NET MVC网址路由最主要的方式。这一条路由定义了三个参数。

Name:路由名称。

Url:设置网址路径如何对应到控制器、动作与路由值。

Default:设置{controller}.{action}.{id}这3个路由参数的默认值。

从几个默认的MapRoute可以得知,当在浏览器中输入http://locallhost/Home/About时,在Routing的对应之下,由于网址路径的部分为Home/About,所有会对应出{controller}为Home,而{action}为About,因此ASP.NET MVC就会先进入Controllers目录查找Home控制器(也就是HomeController.cs文档),然后再查找该控制器内的About公开方法(Public Method),这个公开方法就是MVC的动作(Action),也就是实际运行网页程序的入口点。

当在浏览器中输入http://locallhost/想要取得首页时,在Routing的对应之下,由于网站路径的部分没有任何属性,所以使用MapRoute的第三个参数(defaults)所设置的默认值来替代,因此网站首页的网址就会先进入Controllers目录查找Home控制器,然后再查找Index这个公开方法,来进一步运行ASP.NET MVC的所有过程。

我们先来看一下默认的HomeController的属性:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

 

namespace MvcGuestbook.Controllers

{

    public class HomeController : Controller

    {

        public ActionResult Index()

        {

            ViewBag.Message = "修改此模板以快速启动你的 ASP.NET MVC 应用程序。";

 

            return View();

        }

 

        public ActionResult About()

        {

            ViewBag.Message = "你的应用程序说明页。";

 

            return View();

        }

 

        public ActionResult Contact()

        {

            ViewBag.Message = "你的联系方式页。";

 

            return View();

        }

    }

}

首先,控制器(Controllers)类别在开发的时候必须符合以下规范:

类别名称一定要由Controller结尾。例如:GuestbookController就代表Guestbook控制器。

类别继承于Controller基类

类别中须包含数个回传值为ActionResult的公开方法,这些方法在ASP.NET MVC中成为动作(Action)。

 在默认首页Indexx动作中,第一行的ViewBag是一个动态(dynamic)类型的对象,因此该对象可以设置任意类型的数据进去,这里所指定的属性与值都可以在ASP.NET MVC的View中读取。

ViewBag.Message=”修改此模板以快速启动你的ASP.NET MVC应用程序。”;

第二行的return View();事实上是来自于Controller基类的一个辅助方法(Helper Method),它会回传一个ViewResult对象。ViewResult是继承自Action'Result类,主要用途是告知ASP.NET MVC框架我要响应一个视图(View),而该视图就来自于ASP.NET MVC框架所设置的“默认路径”,以Home控制器与此Index动作为例,通过View()辅助方法就会去告知ASP.NET MVC框架:“我要显示Views/Home/Index.cshtmlz这张网页的运行结果”。

接着,我们用Visual Studio的新增功能切换至该激活的视图,先将光标移至动作方法的定义处,然后单击鼠标右键,在弹出的快捷菜单中选择“转到视图”命令,从该视图的页面属性可以发现,页面中一开始就是@开头的语法,如图5所示,这个语法是从ASP.NET

MVC 3开始新增的Razor语法,跟以往我们撰写ASP.NET MVC2.0或ASP.NET Web Form的ASPX差异甚大,但新版的Razor语法让套用程序的View页面变得非常干净。

 

                图5 该动作(Action)相对应的视图(View)

 

 不过当你仔细一看,你会发现这个Index.cshtml页面并不是一个完整的HTML页面,以往我们在ASP.NET Web Form或ASP.NET MVC 2.0中会套用MasterPage属性来套用主版面,但ASP.NET MVC4.0的主版面到哪去了呢?

   这时我们先通过解决方案资源管理器浏览到项目的Views目录,该目录里面有个_ViewStart.cshtml文档,如图6所示,这个文档会在所有View运行之前先装入,通常我们会在这个文档里设置View的一些基本属性,例如,要装入的主版页面(Layout Page)。

      

图6 浏览至解决方案管理器中的_ViewStart.cshtml文档

打开_ViewStart.cshtml文档,其中定义了一个Layout属性,并指向到~/Views/Shared/_Layout.cshtml主版页面,这也代表了在Views目录下所有的视图(View)都会默认装入该主版页面,如图7所示

 

图7 _ViewStart.cshtml文档的属性

 打开~/Views/Shared/_Layout.cshtml主版页面后,会发现这里含有的完整的HTML结构,如图8所示

 

图8 ~/Views/Shared/_Layout.cshtml文档的属性

我们刚刚在Controller中看到ViewBag.Message被设置了一个字符串,到了Index.cshtml视图(View)

就可以通过以下语法将其信息读出,并显示于网页属性中,如图9所示

@ViewBag.Message

 

   图9 Views\Home\Index.cshtml文档的属性

 另外,在Index.cshtml页最上方也设置了一组ViewBag.Title属性,这里所定义的属性值也会自动被传入同一个View以及默认的_Layout.cshtml的主版页面里,如图10所示

 

图10  Views\Shared\_Layout.cshtml文档的属性

2创建模型

创建模型的操作页面如下:

第一步:在“解决方案资源管理器”窗口中选择Models目录,单击鼠标右键,在弹出的快捷菜单中选择“添加”->“类”命令。

第二步:我们将类取名为Guestbook.cs,并单击“添加”按钮,如图11所示

 

图11 设置类名称

第三步:新增一个简单类,定义出一个留言板所需的数据模型,其程序代码如下:

namespace MvcGuestbook.Models

{

    public class Guestbook

    {

 

        public int Id { get; set; }

        public string 姓名 { get; set; }

        public string Email { get; set; }

        public string 内容 { get; set; }

 

 

    }

}

第四步:s生成一次解决方案,并确认没有任何问题。

 

 

 

3.创建控制器、动作和视图

步骤如下:

第一步:在“解决方案资源管理器”窗口中选择Controller目录,单击鼠标右键,在弹出的快捷菜单中选择“添加”->“控制器”命令

第二步:在“添加控制器”对话框的“控制器名称”文本框中输入控制器名称“GuestController”。

另外,在基架(Scaffold)选项中还有4个选项可设置,这些是Visual Studio2012提供的代码生成器模板设置值,只要妥善设置这些参数,就能利用Visual Studio2012开发工具快速帮助我们生成Controller程序代码。不仅如此,在Visual Studio2012内建的AS.NET MVC4项目模板里,甚至可以在创建Controller的同时直接将View也创建完成。

   在这里,我们在“模板”下拉列表框中选择“包含读/写操作和视图的MVC控制器(使用Entity Framework)”选项,而在“模型类”下拉列表框中选择 步骤1新增的Guestbook模型类别,如图12所示

 

  图12 为控制器命名并设置基架选项

第三步:在“添加控制器”对话框的“基架选项”中还有个数据“上下文类”下拉列表框,由于我们尚未创建“数据上下类”,但我们可以借此通过这个新增项目精灵帮我们自动创建,因此在这里我们可以选择“<新建数据上下文...>”选项。

第四步:选择之后默认会帮你填上“项目名称”+Context作为类别的名称,你可以更改它,或者直接沿用默认值也可以。在这里我们直接以默认的命名继续,单击“确认”按钮完成,如图13所示。

 

图13 新数据上下文

第五步:单击“添加”按钮完成,如图14所示

 

            图14 单击“添加”按钮新增控制器

此时,Visual Studio2012会新增一个新的Controller类别档,名为GuestbookController.cs,在Controller目录下。此外,由于在添加控制器时我们选用“包含读/写操作和视图的MVC控制器(使用Entity Framework)”模板,所以除了新增控制器之外,它连同所有视图页面(View Page)也全部一次创建完成。而我们在添加控制器的过程中新增了一个数据上下文类(DataContextClass),因此在Model目录下多一个MvCGuestbookController.cs,如图15所示

 

图15 通过Visual studuo2012自动新增的控制器,视图页面与信息内容类

4.测试当前创建好的留言板网页

运行“调试”->”启动调试”命令将网站运行起来。网页运行起来后,必须更改URL进入我们刚刚新增的Guestbook控制器来查看页面。以图16所示,打开网页的网址是http://locallhost:7271/,我们在网址路径部分加上Guestbook,网址会变成http://locallhost7271/Guestbook,最后按Enter键进入该页面。

 

 

图16 更改网址以进入Guestbook页面

  进入该页面后,你会看到一些基本页面与Guestbook相关字段。这是一个列表页面,但还没有任何信息,所以当前还看不到任何其他属性。这个页面中还有一个Create New链接,这是进入“创建留言”页面的链接,直接单击进入,如图17所示

 

17 显示Guestbook的默认页面

 进入到Create New页面后,会看到有个默认的窗体,有三个字段分别跟我们之前创建的Guestbook模型类的属性一样。我们直接在这三个字段上输入相对应的数据,然后单击Create按钮输出窗体,如图18所示

 

18 GuestbookCreate页面

接着会回到Index页面,此时你就会发现数据已经写入数据库了!如图19所示

 

     图19 回到Guestbook的默认Index页面

然后,我们再来测试Edit功能,编辑刚刚输入的留言,看到的界面和刚刚Create的页面类似,但是刚输入的数据会自动带入。我们更改“姓名”字段上的文字,如图20为例,在姓名后面加上“(TEST)”字样,最后单击Save按钮保存。

 

20 显示Guestbook的默认Edit页面

此时你会看到该数据“姓名”字段已经被更新成功,如图21所示

 

21 回到Guestbook的默认Index页面

最后我们再测试Delete功能。这里会先显示当前数据库中的数据,如图22所示

 

22 显示Guestbook的默认Delete页面

5.查看数据库属性

 

   当确定数据被写入成功,那我们怎么能知道数据保存到哪里去?如果你完全按照本书步骤创建出第一个项目,那么你应该会在项目的App_Data目录下发现一个隐藏的数据库文档,为了在解决方案资源管理器中看到这些不在项目范围内的文档,必须先单击解决方案资源管理器的“显示所有文件”按钮,再展开App_Data文件夹,即可坎肩相关文档,如图

23所示

 

图23 显示所有文件

6.了解自动生成的程序代码

        刚刚创建的那些完整功能的程序代码都是Visual Studio2012的ASP.NET MVC4项目模板帮我们自动创建的,这样的话我们学不到知识。接下来,我们将逐步了解这些通过工具帮我们生成的程序代码。

  1.了解列表页面的Index动作

我们先打开Controller目录下的GuestController.cs来看看,在GuestbookController类内的第一行定义了一个名为db的类别私有变量,其类别为MvcGuestbookContext,也就是我们的数据内容类,在这整份Controller类别中都将会用到db这个变量对数据库进行访问,如图24所示。

 

图24 GuestbookController类别中的MvcGuestbookContext类别对象

图24所示Index这个公开方法(public method)的程序代码很简单,只有一行,其中View()是来自Controller基类的一个辅助方法(Helper Method),该辅助方法有8个多载,其中第3个多载是闯入一个model参数,此参数的对象数据将会传递给View使用。

我们在这里传入的是db.Guestbooks.ToList(),也代表着把所有Guestbooks回传的所有数据全部传入View中,让View里的程序去使用。接着如图25所示,切换至Index动作方法(Action Method)所对应的视图页面(View Page)。将光标移至return View(db.Guestbooks.ToList()),点击右键,单击转到视图。

2.了解列表页面的Index视图

在Views\Guestbook\Index.cshtml视图页面的第一行,便是一个@model的声明,后面接着一个类别,而该类别是一个Guestbook的集合对象(IEnumerable),所代表的是这个View将会以这个用@model声明的类被为“主要模型”,在View里面的程序代码也将会参考到该类别来使用。

 

接下来的这段ViewBag.Title的设置在本页里并没有用到,而是要传给主版页面(Layout Page)用的,将会显示在HTML的<title>卷标里。

 

   接着我们看到以下这段,是用来创建一个ASP.NET MVC的链接,链接显示名称为“Create New”,而该链接将会链接到当前这也的控制器的Create动作(Action),至于超链接的输出则由ASP.NET MVC负责。

 

由于这是列表页面,所以会有一个<table>标签,代表着要将数据输出成表格,而表格自然会有字段标题,因此会看到以下网页程序片段:

 

这里的@Html.DisplayNameFor辅助方法的主要用途是输出特定字段的显示名称,传入的参数则是以一个Lambda Expression表示法,该表示法里的model变量代表的正是我们在View里第一页设置的@model类别,所以我们可以在挑选字段时,就利用Visual Studio2012的Intellisense来帮助我们进行选择。

  使用@Html.DisplayNameFor默认会直接输出属性名称,所以上述程序最后输出的HTML如下:

 

如果要输出的显示名称和属性名称不同,则必须更改Guestbook模型类别的定义,特定属性(Property)上加上一个System.ComponentModel命名空间下的DisplayName属性(Attribute),在这里我们将Email字段显示名称更改为“电子邮件地址”,如图26所示

 

图26 在Model里加上DisplayName属性(Attribute)

修改完Model的定义后,View里的程序完全不用改,按F5运行网站,Email字段所输出的域名就会直接变成“电子邮件地址”,如下:

 

 在View里的最后一段Code是一个foreach循环,且数据来自于Model对象,这里的Model对象是每个View都有的属性,代表的就是从Controller传过来的数据,而这个Model对象本身是一个泛型类别,也就是说,这个Model对象的了类别会完全等同于你在View最上方用@model声明的那个类别。

   如下程序代码所示,我们通过循环去除Model里的每条数据,而每条数据的类别正好是MvcGuesrbook.Models.Guestbook模型类别。

 

刚刚我们介绍过了@Html.DisplayNameFor辅助方法,则在这儿看到的是@Html.DisplayFor辅助方法,由于这段Code被包含在@foreach循环之中哦那个,所以传入@Html.DisplayFor

D模型的数据。

   3.了解创建信息窗体的Create动作

接着我们来看创建信息功能的动作(Action),切换回GuestbookController类别里,看一下在这个控制器里有两个同名的Creeate方法,从批注这里可以发现,第一个是给HTTP GET方法用的,另一个是给HTTP POST方法用的。

在这里值得一提的是,在第二个Create方法有特别套用一个HttpPost属性(Attribute),该属性告知ASP.NET MVC框架此动作(Action)只会接受HTTP POST过来的信息,这个属性又有一个专有名词称为动作过滤器(Action Filter)或动作选择器(Action Selector)。

 //

        // GET: /Guestbook/

 

        public ActionResult Index()

        {

            return View(db.Guestbooks.ToList());

        }

 

        //

        // GET: /Guestbook/Details/5

 

        public ActionResult Details(int id = 0)

        {

            Guestbook guestbook = db.Guestbooks.Find(id);

            if (guestbook == null)

            {

                return HttpNotFound();

            }

            return View(guestbook);

        }

 

        //

        // GET: /Guestbook/Create

 

        public ActionResult Create()

        {

            return View();

        }

 

        //

        // POST: /Guestbook/Create

 

        [HttpPost]

        public ActionResult Create(Guestbook guestbook)

        {

            if (ModelState.IsValid)

            {

                db.Guestbooks.Add(guestbook);

                db.SaveChanges();

                return RedirectToAction("Index");

            }

 

            return View(guestbook);

        }

 

        //

 

首先,我们进入http://localhost:10752/Guestbook/Create页面时,此时的HTTP要求方法一定是GET方法,因此第一个Create()动作会先被ASP.NET MVC选中来运行,并显示默认的Create视图页面(View Page)。

   我们现在切换至Create的视图页面。

4了解创建信息窗体的Create视图

   在Create.cshtml里面跟刚刚的Index.cshtml一样,一开始就是先来个@model声明,声明此页面以MvcGuestbook.Models.Guestbook为主要模型。

 

接着则出现一个ASP.NET MVC的窗体声明,与窗体内的HTML声明,代码如下:

@using (Html.BeginForm()) {

    @Html.ValidationSummary(true)

 

    <fieldset>

        <legend>Guestbook</legend>

 

        <div class="editor-label">

            @Html.LabelFor(model => model.姓名)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.姓名)

            @Html.ValidationMessageFor(model => model.姓名)

        </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.内容)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.内容)

            @Html.ValidationMessageFor(model => model.内容)

        </div>

 

        <p>

            <input type="submit" value="Create" />

        </p>

 </fieldset>

}

这里使用的是Html.BeginForm()辅助方法,该辅助方法将会输出<form>标签,而且必须以using包起来,如此便可在using程序代码最后退出时,让ASP.NET MVC帮你补上</form>标签。以本页为例,最后窗体输出的HTML结构如下:

<form action=”/Guestbook/Create” method=”post”>

...

</form>

接下来的这段是用来显示当表单域发生验证失败时,显示的错误信息:

@Html.ValidationSummary(true)

在这个创建信息的窗体里一共有三个字段,你会发现这三个字段的定义都差不多,如下代码段所示:

 <div class="editor-label">

            @Html.LabelFor(model => model.姓名)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.姓名)

            @Html.ValidationMessageFor(model => model.姓名)

        </div>

 

        <div class="editor-label">

这里的@Html,LablleFor用来显示特定字段的显示名称。而刚刚也介绍过一个@HTML

.DisplayNameFor,这两个辅助方法其实只有些微差异,你可以参考表1,用@Html.DisplayNameFor只会输出域名,而使用@Html.LabelFor则会输出包含<Lable>标签的域名。

Razor语法

HTML输出结果

@Html.DisplayNameFor(model=>model.Email)

电子邮件地址

@Html.LabelFor(model=>model.Email)

<label for=”Email”电子邮件地址</label>

 

  在ASP.NET MVC 里主要使用@Html.EditorFor来输出表单域,以此字段为例,输出的HTML代码段如下,这里出现的class属性是默认输出的,你可以借助此设计一些CSS样式来改变该输出字段的样式。

<input class=”text-box single-line” name=”姓名” type=“text” value=””/>

最后一个@Html.ValidationMessageFor是用来显示字段验证的错误信息,不过,当前为止,在这个Create页面里,我们并没有做出任何字段验证的设置。

  在ASP.NET MVC里,窗体验证可以用一种极其简单的方式进行设置,而且只要在Model里进行定义即可同时解决客户端与服务器端验证的工作。我们再次开启Guestbook模型类别,并在需要必填的属性加上一个System.ComponentModel.DataAnnotations命名空间下的Required属性(Attribute),如图27所示

 

图27 在Model里加上Required必填属性(Attribute)

修改完Model定义后,跟刚刚一样,View里的程序完全不用更改,按F5键运行网站。不过这次运行出现了一个Entity Framework Code First的运行时期错误,其错误如图28所示

 

   解决这个问题最简单的方法就是好将数据库整个砍掉重建,由于我们现在还处于练习ASP.NET mvc快速上手的截断,所以请参照一下步骤设置。我们由Entity Framework帮助我们运行重建数据库的动作。不过请特别注意,这里仅为了教学方便才这样设置,在生产环境下千万不要启动一下参数,否则将数据库砍掉后,所有已经输入数据库的数据都将会消失。

  还记得我们在创建控制器时曾经创建过一个MvcGuestbookContext.cs文档在Models目录下,打开此文档后,会发现有段批注帮助我们如何如何让Entity Framework自动卸载再重新生成数据库的方式,其中还包括可以让你直接复制、粘贴的演示程序代码:

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值