MVC5+EF6 入门完整教程3 :EF完整开发流程
https://www.cnblogs.com/miro/p/4053473.html
学完本篇文章,你将会掌握基于EF数据模型的完整开发流程。
本次将会完成EF数据模型的搭建和使用。
基于这个模型,将之前的示例添加数据库查询验证功能。
文章提纲
概述 & 要点
详细步骤
总结
概述 & 要点
下面是本文要点,正文部分会有详细介绍。
- EF架构图
- 新建基于EF的Data Model的约定
- 关于ORM的重要概念,和传统方式开发的区别
- EF开发的整体过程
详细步骤
- 新建文件夹,规划好代码摆放位置
- 创建相关类 (Data Model)
- 创建 Database Context
- 创建Initializer, 使用EF初始化数据库,插入示例数据
- 完成数据库查询验证
新建文件夹,规划好代码摆放位置
- 根目录下新建一个 ViewModels文件夹。
Models文件夹里面存放对应于数据库表的实体。
View中需要显示的数据和Models中实体模型不一定能对应上, 因此需要专门给View使用的自定义数据模型,我们称之为ViewModel , 放在ViewModels文件夹里面。
- 根目录下新建一个DAL 文件夹。
DAL 放置数据访问相关类。
NOTE 本文中放AccountContext.cs, AccountInitializer.cs

创建相关类(Data Model)
为了更加贴近真实情况,我们针对用户建立三个相关的类。
SysUser, SysRole, SysUserRole
这是用户权限管理RBAC (Role – Based Access Control)的一个典型模型, 更复杂的模型都可以在这个基础上进行扩展。
OK,下面我们就开始新建这个模型。
我们先去网上找个大致的关系图做参考,打开百度,输入 user role , 搜索图片。
挑一个类似的做参考。

NOTE 权限相关是系统管理范畴的,不涉及具体业务,我起名字的时候都加了Sys前缀,这样和业务区隔开来。
参考上面这个图建立 Data Model
SysUser Entity

SysRole Entity

SysUserRole Entity

对于上面几个类的约定和说明:
- EF生成数据库时,ID 属性将会成为主键。(约定:EF默认会将ID或classnameID生成主键, MSDN建议保持风格的一致性, 都用ID或classnameID, 我们这里都用ID)
- EF 生成数据库时 , <navigation property name><primary key property name>这种形式的会成为外键. ( 约定 )
例如外键 SysUserID = SysUser(navigation property)+ID(SysUser的主键)
- 定义为virtual的几个属性是 navigation 属性(virtual非必须, 只是惯例用法, 后面文章将会讲解用virtual的好处).
navigation 属性保存着其他的关联entity(entities)
示例中, SysUser和SysUserRole是一对多的关系, SysRole和SysUserRole也是一对多的关系.
如果是 "多", 属性类型就必须是list( 这里用的是Icollection )
创建 Database Context
前置条件:安装EF
打开 工具库程序包管理器à程序包管理器控制台
输入 install-package entityframework


去MSDN上查看下EF的架构图:http://msdn.microsoft.com/en-us/data/aa937709

从上图可以看出,EF框架在底层是通过调用ADO.NET来实现数据库操作的。
多转一道弯,性能和灵活性肯定会受到影响,所以本系列文章结束后同样也会给出MVC+ADO.NET的方案,大家可以根据需要选择。
NOTE
微软官方推出的ORM框架主要有Linq to SQL和Entity Framework.
EF是目前最新的,也是推荐配合MVC使用的框架。
实际操作前再补充一些重要概念:
如果不用ORM框架,我们一般这样来使用ADO.NET进行数据库开发:
- 将ADO.NET对数据库的操作封装到一个类里SqlHelper中
- 在DAL层调用SqlHelper
- 其他层再调用DAL进行数据库操作
使用ORM之后,以前面的SysUser为例:
O(Object) ---> 程序中的类 SysUser, 就是对象
R (Relation) ---> 数据库中的表
M(Mapping) ---> O和R的映射关系
ORM对传统方式的改进:
充当桥梁,实现了关系数据和对象数据的映射,通过映射自动产生SQL语句。
对常用的操作,节省了写SQL语句的步骤。
好了,现在必要的概念应该理解了吧,下面我们就进行实际的操作了。
创建类 AccountContext.cs , 让他继承自System.Data.Entity.DbContext, 这个类完成EF的功能。

主要做下面三件事:
- 为每个entity set创建一个DbSet
在EF中,通常情况下一个entity set对应数据库中的一张表,一个entity对应表中的一行。
- 指定一个连接字符串
构造函数中的 base("AccountContext") 。
默认情况下和类名一样,即AccountContext,我们显式的给他指定出来。
- 指定单数形式的表名
>();
默认情况下会生成复数形式的表,如SysUsers
NOTE 表名用单复数形式看各自的习惯,没有明确的规定。有的公司表名全用单数,有的公司根据表的意思,有单数也有复数。

配合上面第2点,配置连接字符串 web.config中给指定了。
如下图,贴着appSettings配置节上面添加。注意要web.config中要加上红字部分,不然会出错。
<connectionStrings>
<add name="AccountContext" connectionString="Data Source=.;database=MvcDemo;uid=sa;pwd=123456;AttachDBFilename=|DataDirectory|\MvcDemo.mdf;"providerName="System.Data.SqlClient"/></connectionStrings>
NOTE AttachDBFilename=|DataDirectory|\MVCDemo.mdf设定了数据库文件的存放位置:在项目根目录的App_Data文件夹下。
创建AccountInitializer, 使用EF初始化数据库,插入示例数据
EF有多种方式建立数据库。
我们采用如下方式:
第一次运行程序时新建数据库,插入测试数据; model改变(和database不一致)时删除重建数据库,插入测试数据。
目前在开发阶段,不用管数据丢失的问题,直接drop and re-create比较方便。
等系列文章结束后会讲解生产环境中如何不丢失数据修改schema
下面我们就新建类AccountInitializer.cs来完成这个工作。

Seed方法用我们之前定义的database context(即AccountContext) 作为参数,通过这个context将entities添加到database中去。(就是我们前面说的桥梁作用)
从上面代码可以看出, Seed方法对每一个entity的类型(我们用了SysUser和SysRole, SysUserRole我们暂不添加):
创建一个colletion ---> 添加到适当的 DbSet property ---> 保存到数据库。
NOTE 不一定要在每个entity组后面都调用SaveChanges方法,可以在所有组结束后调用一次也可以。这样做是因为如果写入数据库代码出错,比较容易定位代码的错误位置。
修改web.config, 通知EF使用我们刚刚写好的AccountInitializer类。
找到entityFramework配置节,添加下图方框处内容。

context 配置节中, type 的值对应 (AccountContext的完整描述,程序集)
databaseInitializer 配置节中 , type 的值对应 (initializer class 的完整描述,程序集)
NOTE : 如果你不想EF使用某个context, 可以将下面方框处设置为true.

完成数据库查询验证
现在EF一切就绪.
运行程序,当第一次连接数据库时,EF比较model(AccountContext和entity classes) 和database. 如果两边不一致,程序将会drop and re-create数据库。
因为目前我们还没有连接数据库的操作,所以EF还没发挥作用。
现在我们完成前面的Login功能。
- 先做点小修改,在Models--->SysUser.cs里面添加个Email字段。
同样DAL--->AccountInitializer.cs--->Seed里面示例数据也要增加这个字段


NOTE 添加一个Email是因为之前的登录页面填入的是Email值,后面将会输入Email和Password到数据库中进行比对。
- 打开Controllers --->AccountController.cs
- Instantiate 一个database context 对象
- 修改HttpPost类型的Login Action,查询数据库进行比对。
NOTE
用过SQL的人都知道,学习SQL,最复杂的是查询,把各种查询学好了,基本就掌握70%以上了。
EF数据模型的数据操作也一样,重点是查询,下篇文章会展开讲。(从简单查询到条件、聚合、连接等复杂查询都会涉及到)

运行Login.cshtml页面(还没有建立Login.cshtm ?),输入正确的和错误的登录信息验证下。


另外再检查一下数据库部分是否符合我们的预期:
- 打开数据库,发现MVCDemo这个数据库已经新建,示例数据已经插入。
- 打开项目的App_Data 文件夹,发现数据库文件已经存在。


总结
OK,到此为止,我们搭建好了EF框架,进行了数据库的初始化,查询了一条用户信息。
需要说明的是,现在的登录功能还比较简陋,不是真正的登录功能(例如输入项还缺少验证,密码还没有加盐),只是为了说明EF的用法。根据系列文章讲述知识点的需要,最终会实现完整功能。
最后再回顾下本篇文章的重点:掌握使用EF开发的整个过程。
创建Data Model---> 创建Database Context ---> 创建databaseInitializer ---> 配置entityFramework的context配置节
希望大家能清晰的了解上面整个过程,理解每一个过程的作用。
MVC5+EF6 入门完整教程3 :EF完整开发流程的更多相关文章
- MVC5+EF6 入门完整教程
MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用 MVC5+EF6 入门完整教程10:多对多关联表更新&使用原生SQL@20150521 MVC5+EF6 入门完整教程9:多表 ...
- MVC5+EF6 入门完整教程九
前一阵子临时有事,这篇文章发布间隔比较长,我们先回顾下之前的内容,每篇文章用一句话总结重点. 文章一 MVC核心概念简介,一个基本MVC项目结构 文章二 通过开发一个最基本的登录界面,介绍了如何从Co ...
- MVC5+EF6 入门完整教程13 -- 动态生成多级菜单
稍微有一定复杂性的系统,多级菜单都是一个必备组件. 本篇专题讲述如何生成动态多级菜单的通用做法. 我们不用任何第三方的组件,完全自己构建灵活通用的多级菜单. 需要达成的效果:容易复用,可以根据mode ...
- MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用
摘要: 第一阶段1~10篇已经覆盖了MVC开发必要的基本知识. 第二阶段11-20篇将会侧重于专题的讲解,一篇文章解决一个实际问题. 根据园友的反馈, 本篇文章将会先对呼声最高的仓储模式进行讲解. 文 ...
- MVC5 + EF6 入门完整教程二
从前端的UI开始 MVC分离的比较好,开发顺序没有特别要求,先开发哪一部分都可以,这次我们主要讲解前端UI的部分. ASP.NET MVC抛弃了WebForm的一些特有的习惯,例如服务器端控件,Vie ...
- MVC5+EF6 入门完整教程12--灵活控制Action权限
大家久等了. 本篇专题主要讲述MVC中的权限方案. 权限控制是每个系统都必须解决的问题,也是园子里讨论最多的专题之一. 前面的系列文章中我们用到了 SysUser, SysRole, SysUserR ...
- MVC5+EF6 入门完整教程 总目录
本系列文章会从一个主干开始,逐渐深入,初步规划30篇.初级10篇,中级10篇,综合项目实战10篇 初级10篇 MVC5+EF6 入门完整教程10:多对多关联表更新&使用原生SQL@201505 ...
- MVC5 + EF6 入门完整教程1
https://www.cnblogs.com/miro/p/4030622.html 第0课 从0开始 ASP.NET MVC开发模式和传统的WebForm开发模式相比,增加了很多"约定& ...
- MVC5 + EF6 入门完整教程(转载)--01
MVC5 + EF6 入门完整教程 第0课 从0开始 ASP.NET MVC开发模式和传统的WebForm开发模式相比,增加了很多"约定". 直接讲这些 "约定&qu ...
- ASP.NET MVC5 + EF6 入门教程 (6) View中的Razor使用
文章来源: Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc-5-ef-6-get-started-model.html 上一节:ASP.NET MVC ...
随机推荐
- 二分类模型之logistic
liner classifiers 逻辑回归用在2分类问题上居多.它是一个非线性的回归模型,其最大的好处恰恰是可以解决二元类问题,目前在金融行业,基本都是使用Logistic回归来预判一个用户是否为好 ...
- PAT 基础编程题目集 6-10 阶乘计算升级版 (20 分)
本题要求实现一个打印非负整数阶乘的函数. 函数接口定义: void Print_Factorial ( const int N ); 其中N是用户传入的参数,其值不超过1000.如果N是非负整数,则该 ...
- Hdu1042 N! (阶乘高精度模板)
Problem Description Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N! Input One N in ...
- PIE-SDK For C++栅格数据的创建
1.功能简介 目前在地理信息领域中数据包括矢量和栅格两种数据组织形式.每一种数据有不同的数据格式,目前PIE SDK支持多种数据格式的数据创建,下面对栅格数据格式的数据创建功能进行介绍. 2.功能实现 ...
- 检测到 LoaderLock Message: 正试图在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。
解决方法: 调试状态=>异常(Ctrl+Alt+E)=>Managed Debuggin Assistants=>LoaderLock 的选中状态去掉即可.
- C#使用OracleBulkCopy
首先使用PL/SQL 通过语句:select * from v$version; 查询出使用的oracle版本,弄到对应版本的Oracle.DataAccess.DLL 我本地使用版本为:11.2. ...
- java性能分析 - CPU飙高分析工具
背景 有处理过生产问题的同学基本都能遇到系统忽然缓慢,CPU突然飙升,甚至整个应用请求不可用.当出现这种情况下,在不影响数据准确性的前提下,我们应该尽快导出jstack和内存信息,然后 ...
- 梯度下降算法&线性回归算法
**机器学习的过程说白了就是让我们编写一个函数使得costfunction最小,并且此时的参数值就是最佳参数值. 定义 假设存在一个代价函数 fun:\(J\left(\theta_{0}, \the ...
- JavaDay2(中)
Java循环与分支练习 习题1: 输出1~100内前5个可以被3整除的数. public class Day2_Test1 { //输出1~100内前5个可以被3整除的数. public static ...
- SpringMVC 和 Struts2的区别
SpringMVC 和 Struts2的区别 1.Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方 ...