ASP.Net MVC开发基础学习笔记(7):数据查询页面
前言
前面铺垫了那么多,今天我们就用MVC5 + EF6 + Bootstrap3来正式创建一个基本查询页面。
为什么从查询页面開始?嘿嘿。由于小弟的.Net生涯就是从查询页面開始的,记得正式工作的第一个月就是各种模块的查询。先做查询有什么优点?首先查询仅仅读数据。不写数据。对数据库本身的数据安全不造成影响也不怕写入脏数据的麻烦。其次增删改查这四个操作里面。查询的难度应该是最小的,不用考虑事务流程等方面的问题。
本节最后将会生成例如以下页面:
创建Model
关于Model、数据库上下文、Entity Framework,本系列教程前面已经有介绍
在Models目录下创建一个类,命名为Worker.cs。这个类就是我们这里要用到的Model。代码例如以下:
namespace SlarkInc.Models
{
public enum Sex
{
Male, Female
}
public class Worker
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public Sex Sex { get; set; }
public double? Rating { get; set; }
}
}
为了方便说明。增加行号。假设想要复制代码,请点击左上角的小图标就会出现不带行号的代码。在Worker类的上面,第3行,创建了一个Sex的枚举类型,保证Sex仅仅有Male和Female两种取值。9到13行中Worker类用自己主动属性的方法定义了5个属性。当中Rating属性前面有个问号表示这个属性是nullable,能够是null。
创建数据库上下文DbContext
这里我们用Code First方法创建数据库表。这种方法简单点说就是先创建Model再依据Model生成数据库表。
为了方便起见。这里用的数据库是Visual Studio自带的LocalDb。
数据库上下文。就是我们这里的数据訪问层。依据Model对数据库表进行不同的操作。因此我们首先在项目中创建一个数据訪问层目录。命名为DAL。然后,在DAL目录中创建Model相应的数据库訪问上下文类。命名为CompanyContext。写入代码例如以下:
using System.Data.Entity;
using SlarkInc.Models;
using System.Data.Entity.ModelConfiguration.Conventions; namespace SlarkInc.DAL
{
public class CompanyContext : DbContext
{
public CompanyContext() : base("CompanyContext")
{
} public DbSet<Worker> Workers {get;set;} protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
由于我们这里数据库訪问要用Entity Framework, 所以第1行要引入System.Data.Entity。第7行。我们的数据库上下文继承EF中的DbContext基类。
第9行表示
CompanyContext 继承基类DbContext的构造函数。第13行表示我们的Model Worker和 CompanyContext中的数据集Workers相应。第15到18行定义了一个事件
OnModelCreating,这个事件在我们使用的Code First方法在数据库中创建数据表时触发。
第17行的代码的作用是使我们创建出来的数据库表名字都是单数。不是复数。也就是说将来的数据库表名是Worker而不是Workers。这也是我们创建数据库表的习惯命名方法。
然后在Web.config文件中面增加这个数据库上下文要用到的数据库连接字符串。如以下的代码所看到的,在Web.config文件中找到<configuration>元素。然后在<configuration>元素内找到 <connectionStrings>元素。最后在<connectionStrings>元素内增加例如以下<add>元素。
<configuration>
<connectionStrings>
<add name="CompanyContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=Company;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\Company.mdf" providerName="System.Data.SqlClient" />
</connectionStrings>
<configuration>
这样我们的数据库上下文CompanyContext就能够用这个连接字符串来訪问数据库了。解释一下<add>元素里的内容。name="CompanyContext"是连接字符串的名字,这个要和CompanyContext.cs 里的base("CompanyContext")函数的參数一样,这样初始化数据库上下文的时候才干读到字符串。Data Source=(LocalDb)\v11.0表示使用的数据库种类和版本号。Catalog=Company是数据库的名字。Integrated Security=SSPI是验证方式。
AttachDBFilename=|DataDirectory|\Company.mdf表示在我们这里。数据库文件存在
~\App_Data\Company.mdf 下。providerName="System.Data.SqlClient"表示我们这里要用的数据库连接器。或者叫数据库驱动。
然后我们还要在Web.config中声明数据库上下文。
在<configuration>中找到<entityFramework>元素。在<entityFramework>元素中找到<contexts>元素。在<contexts>元素中写入例如以下<context>元素。
<entityFramework>
<contexts>
<context type="SlarkInc.DAL.CompanyContext, SlarkInc">
</context>
</contexts>
</entityFramework>
type="SlarkInc.DAL.CompanyContext, SlarkInc"中的SlarkInc.DAL.CompanyContext表示这个CompanyContext的NameSpace和类名。
逗号后面的SlarkInc表示这个CompanyContext在SlarkInc.dll中。
这样我们就把CompanyContext加入到了Entity Framework的上下文中。
创建初始化数据
为了方便測试,我们须要在数据库创建好之后给当中加入一些数据。
因此我们来创建一个数据初始化类来做这个工作。
在DAL目录中创建一个类。命名为CompanyInitializer.cs。写入例如以下代码:
using System.Collections.Generic;
using SlarkInc.Models; namespace SlarkInc.DAL
{
public class CompanyInitializer : System.Data.Entity.DropCreateDatabaseAlways<CompanyContext>
{
protected override void Seed(CompanyContext context)
{
var students = new List<Worker>
{
new Worker{FirstName="Andy",LastName="George",Sex = Sex.Male},
new Worker{FirstName="Laura",LastName="Smith",Sex = Sex.Female},
new Worker{FirstName="Jason",LastName="Black",Sex = Sex.Male},
new Worker{FirstName="Linda",LastName="Queen",Sex = Sex.Female},
new Worker{FirstName="James",LastName="Brown", Sex = Sex.Male}
};
students.ForEach(s => context.Workers.Add(s));
context.SaveChanges();
}
}
}
第6行,我们的数据初始化类继承了一个名为DropCreateDatabaseAlways的泛型类。这个类的作用就像它的名字,每次程序执行时都会删除并又一次创建数据库,这样方便我们測试。第8到20行,就是初始化数据的函数。重写了父类的Seed函数,并接受CompanyContext 作为数据库上下文供我们操作。
第18行用Linq语法将 students的数据加入到数据库上下文的数据集中。第19行。将这些数据提交到数据库。
然后要在Web.config文件里配置这个初始化器。
在刚才配置过的<context>中写入例如以下所看到的的databaseInitializer就可以。
<contexts>
<context type="SlarkInc.DAL.CompanyContext, SlarkInc">
<databaseInitializer type="SlarkInc.DAL.CompanyInitializer, SlarkInc" />
</context>
</contexts>
type="SlarkInc.DAL.CompanyInitializer, SlarkInc"中的SlarkInc.DAL.CompanyInitializer表示这个CompanyInitializer的NameSpace和类名。逗号后面的SlarkInc表示这个CompanyInitializer在SlarkInc.dll中。
这样我们的初始化器就完毕了。
创建Controller
Controller没学好的同学请猛戳我!
在Controllers目录下创建一个Controller选择"MVC 5 控制器 - 空",命名为CompanyController.cs。
写入代码例如以下:
using System.Linq;
using System.Web.Mvc;
using SlarkInc.DAL;
namespace SlarkInc.Controllers
{
public class CompanyController : Controller
{
private CompanyContext db = new CompanyContext();
public ViewResult Index()
{
return View(db.Workers.ToList());
}
}
}
为了使用之前创建的Model和数据库上下文,在第3行引入DAL命名空间并在第9行初始化CompanyContext。在第12行创建Index Action返回类型是ViewResult。那么用户请求就会返回一个View页面。然后在第12行把全部的数据传递给View。第12行ToList方法是把数据以List的形式输出。
创建View
要创建CompanyController的Index Action相应的View,首先在Views目录下创建Company目录。然后在Company目录下创建一个空视图并选择使用布局页。命名为Index.cshtml。写入例如以下代码:
@model IEnumerable<SlarkInc.Models.Worker>
<table class="table">
<tr>
<th>@Html.DisplayNameFor(model => model.FirstName)</th>
<th>@Html.DisplayNameFor(model => model.LastName)</th>
<th>@Html.DisplayNameFor(model => model.Sex)</th>
<th>@Html.DisplayNameFor(model => model.Rating)</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Sex)
</td>
<td>
@Html.DisplayFor(modelItem => item.Rating)
</td>
</tr>
}
</table>
第1行。表示这个页面用的Model是我们创建的Worker类。
以下的代码创建了一个table。用来显示Controller传来的数据。
4-7行通过
DisplayNameFor获取Model的属性名作为列头显示。第9-25行通过DisplayFor函数显示数据。
查看结果页面
选择在浏览器中查看。就能看到例如以下显示结果。
页面的头部和尾部应用了~/Views/Shared/_Layout.cshtml的默认布局。
中间部分就是在Index.cshtml文件生成的表。当中的4列是Model Worker中除了id外的其他4列数据。
表里的五行数据是我们在~/DAL/CompanyInitializer.cs中初始化的数据。
右键点击页面表格中的不论什么一个数据,选择检查元素,例如以下图所看到的。
这样在F12开发者工具窗体的右側就会有相应元素的css样式。
因为我们在Index.cshtml中设置了<table class="table">因此这个表格的全部元素都会套用Bootstrap的表格样式,例如以下所看到的。
查看数据库
在解决方式资源管理器中点击例如以下图所看到的的显示全部文件button使全部文件显示。
然后在App_Data下会出现一个CompanyContext.mdf的数据库文件。例如以下图所看到的。
双击这个文件,会出现server资源管理器窗体例如以下图所看到的:
能够看到两个数据库连接。不用操心。第一个是我们执行程序后生成的连接,第二个是刚才双击mdf文件生成的连接。两个连接效果是一样的。
双击第二个连接的"表"目录下的Worker表。就能够查看我们用EF Code First 方法生成的表了。显演示样例如以下:
左上方是表结构,右上方是表的其它属性,下方是生成表用的SQL语句。
在server资源管理器中右键点击Worker表,选择"显示表数据"就会显演示样例如以下图的全部数据,是不是和页面显示的一样呢?
结尾
这一节我们应用MVC5 + EF6 + Bootstrap3创建了第一个正式的数据查询页面。后面我们会给这个页面增加keyword查询、分页、排序等功能。
为了实现这些功能我们会介绍很多其它的EF函数及Linq的用法。敬请期待。
ASP.Net MVC开发基础学习笔记(7):数据查询页面的更多相关文章
- ASP.Net MVC开发基础学习笔记:一、走向MVC模式
一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...
- ASP.Net MVC开发基础学习笔记(1):走向MVC模式
一.ASP.Net的两种开发模式 1.1 ASP.Net WebForm的开发模式 (1)处理流程 在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/bl ...
- ASP.Net MVC开发基础学习笔记:二、HtmlHelper与扩展方法
一.一个功能强大的页面开发辅助类—HtmlHelper初步了解 1.1 有失必有得 在ASP.Net MVC中微软并没有提供类似服务器端控件那种开发方式,毕竟微软的MVC就是传统的请求处理响应的回归. ...
- ASP.Net MVC开发基础学习笔记:三、Razor视图引擎、控制器与路由机制学习
一.天降神器“剃须刀” — Razor视图引擎 1.1 千呼万唤始出来的MVC3.0 在MVC3.0版本的时候,微软终于引入了第二种模板引擎:Razor.在这之前,我们一直在使用WebForm时代沿留 ...
- ASP.Net MVC开发基础学习笔记:四、校验、AJAX与过滤器
一.校验 — 表单不是你想提想提就能提 1.1 DataAnnotations(数据注解) 位于 System.ComponentModel.DataAnnotations 命名空间中的特性指定对数据 ...
- ASP.Net MVC开发基础学习笔记:五、区域、模板页与WebAPI初步
一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...
- ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步
一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...
- ASP.Net MVC开发基础学习笔记(4):校验、AJAX与过滤器
一.校验 — 表单不是你想提想提就能提 1.1 DataAnnotations(数据注解) 位于 System.ComponentModel.DataAnnotations 命名空间中的特性指定对数据 ...
- ASP.Net MVC开发基础学习笔记(3):Razor视图引擎、控制器与路由机制学习
一.天降神器“剃须刀” — Razor视图引擎 1.1 千呼万唤始出来的MVC3.0 在MVC3.0版本的时候,微软终于引入了第二种模板引擎:Razor.在这之前,我们一直在使用WebForm时代沿留 ...
随机推荐
- cocos2d-x JsonBox 读写
#include "JsonBox.h" std::string path = "test.json”; //注意引入路径 path = cocos2d::CCFileU ...
- css 图标 旋转中
.person-loading .loading-icon{position: absolute;top: 14px;} i.loading-icon{width: 15px;height: 15px ...
- 原声js实现addClass removeClass toggleClass效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- oracle 实现插入自增列(类似SqlServer Identity)
oracle不像sql server 有关键字identity直接可插入数据时自增 ,Oracle是不能用Identity,可以使用Sequence Create Table Tempinfo( id ...
- eclipse egit 解决冲突
eclipse egit冲突解决 在 pull 代码的时候 ,从远程仓库与本地仓库进行同步的时候 ,如果服务器版本与本地仓库版本不一致, 需要解决冲突 首先需要将改动的代码commit到本地仓库,冲 ...
- 第2章 初学 emWin 的准备工作及其快速上手
以下内容转载自安富莱电子论坛:http://forum.armfly.com/forum.php?mod=viewthread&tid=24552&extra=page%3D3%26f ...
- string.h中的库函数
虽然面试的时候,都会叫你不使用c库函数,自己完成某某函数的编写,但是库函数毕竟更让人信赖,我们没有任何理由怀疑库函数而使用自己的版本.不过当做练习,自己还是可以实现一下的.这里记录一下5th c pr ...
- 【Unity】关于发射子弹、导弹追踪的逻辑
做个笔记,之后补上. 一.发射子弹 网上搜到的基本是两种方法: 给子弹物体添加一个力 AddForce. 子弹物体挂一个运动脚本,Update中毎帧向前运动.通过调整子弹生成点的Transform来控 ...
- 利用AbstractRoutingDataSource实现动态数据源切换
需求:系统中要实现切换数据库(业务数据库和his数据库) 网上很多资料上有提到AbstractRoutingDataSource,大致是这么说的 在Spring 2.0.1中引入了AbstractRo ...
- jquery方法操作iframe元素
操作iframe父元素 $("#rolesCtl",parent.document).find( 'button' ).trigger( 'click' ); 在父页面获取ifra ...