MVC5 + EF6 入门完整教程 四
来源:互联网 发布:网络恐怖主义的成因 编辑:程序博客网 时间:2024/05/22 03:05
跟着这个教程学习,已经将自己写的代码上传到git上,有需要的可以下载,如有问题欢迎留言,后续会持续更新https://github.com/bloodymandoo/mvc5
上篇文章主要讲了如何配置EF, 我们回顾下主要过程:
创建Data Model à 创建Database Context à创建databaseInitializerà配置entityFramework的context配置节。
对这个过程还有疑问的可以去上篇再看一下。
本次我们就主要讲解 (1) EF基本的CRUD (2) 涉及到的常用HtmlHelper
文章提纲
概述 & 要点
理论基础
详细步骤
总结
概述 & 要点
下面是本文要点,正文部分会有详细介绍。
- EF数据模型的CRUD
- 常用的HtmlHelper
- Repository Pattern
理论基础 -- EF 三种编程方式 (略)
总共有三种方式:
Database First,Model First和Code First,我们采用的是code first.
这方面资料很多,我就不重复讲述了, 需要了解这三者差异和应用场景的请自行查阅其他资料。
理论基础 -- EF CRUD
针对之前创建的SysUser, SysRole, SysUserRole举一些典型例子,基本的CRUD大家在使用时模仿这些例子就可以了。
我们要用的数据库示例数据分别如下:
SysUser
SysRole
SysUserRole
EF数据查询
先讲使用频率最高的查询部分。
EF数据查询用LINQ实现(LINQ to Entities),通常有表达式和函数式两种方式。建议用函数式方式,比较简单。
假设我们已经定义好了context
privateAccountContext db =newAccountContext();
- [基本查询] 查询所有的SysUser
- var users =from uin db.SysUsers
- ct u;//表达式方式
- users = db.SysUsers;//函数式方式
- [条件查询] 加入查询条件
- users =from uin db.SysUsers
- where u.UserName =="Tom"
- select u;//表达式方式
- users = db.SysUsers.Where(u => u.UserName =="Tom");//函数式方式
NOTE 注意这边等号是C#写法 :" =="
- [排序和分页查询]
- users = (from uin db.SysUsers
- orderby u.UserName
- select u).Skip(0).Take(5);//表达式方式
- users = db.SysUsers.OrderBy(u => u.UserName).Skip(0).Take(5);//函数式方式
NOTE 只有排序了才能分页
- [聚合查询]
- //查user总数
- var num = db.SysUsers.Count();
- //查最小ID
- var minId = db.SysUsers.Min(u => u.ID);
NOTE 聚合查询只能通过函数式查询
- [连接查询]
- var users =from urin db. SysUserRoles
- join uin db. SysUsers
- on ur.SysUserIDequals u.ID
- elect ur;
NOTE
大家注意,连接查询返回的结果还是一个类型为SysUserRoles的集合,只是用了内连接进行了的筛选。
那么问题来了,如果我需要选择一个集合,里面包括多张表,如SysUser里面的UserName和SysRole里面的RoleName怎么办?
这个是通过navigation property来实现的, 前面新建model的时候提到过,例如SysUser里面的
publicvirtualICollection<SysUserRole> SysUserRoles {get;set; }
但这种做法还是不是太灵活,具体做法我们在下面的详细步骤里面讲。
EF数据更新
UPDATE步骤比较清晰,直接看下面代码。
- //数据更新,分三步:找到对象--> 更新对象数据--> 保存更改
- public ActionResult EFUpdateDemo()
- {
- //1.找到对象
- var sysUser = db.SysUsers.FirstOrDefault(u => u.UserName =="Tom");
- //2.更新对象数据
- if (sysUser !=null)
- {
- sysUser.UserName ="Tom2";
- }
- //3.保存修改
- db.SaveChanges();
- return View();
- }
EF数据添加/删除
与UPDATE类似。
- //数据添加和删除
- publicActionResult EFAddOrDeleteDemo()
- {
- //添加
- //1.创建新的实体
- var newSysUser =newSysUser()
- {
- UserName ="Scott",
- Password ="tiger",
- Email ="Scott@sohu.com"
- };
- //2.增加
- db.SysUsers.Add(newSysUser);
- //3.保存修改
- db.SaveChanges();
- //删除
- //1.找到需要删除的对象
- var delSysUser = db.SysUsers.FirstOrDefault(u => u.UserName =="Scott");
- //2.删除
- if (delSysUser!=null)
- {
- db.SysUsers.Remove(delSysUser);
- }
- //3.保存修改
- db.SaveChanges();
- return View("EFQueryDemo");
- }
详细步骤
- 查询用户及相应角色的功能
- 修改用户
- 增加用户和删除用户
查询用户及相应的角色
- 在Controller中修改Index方法,添加相关View, 显示所有用户
- 将model作为参数传过去
- Viewsà Accountà Index.cshtml 顶部添加强类型声明,
@modelIEnumerable<MVCDemo.Models.SysUser>
body中添加个table用来显示数据
NOTE
@Html.ActionLink("Details","Details",new { id = item.ID })生成一个相同controller下的路由地址。
显示结果
- 增加一个Details方法,添加相关View, 显示相应用户及对应的角色
- 将特定的model传过去
- Viewsà Accountà Index.cshtml 顶部添加强类型声明
@modelMVCDemo.Models.SysUser
显示数据,注意方框部分如何导航到另外一张表的信息中。
显示结果
更新用户,增加用户,删除用户
这三个操作都类似,属于更新的范畴,我们放在一起来讲。
- 修改Viewsà Accountà Index.cshtml
开头增加Create链接。
table每条记录后面增加Edit,Delete链接。
- 在Controller中增加相应的方法。
新建用户:
- //新建用户
- public ActionResult Create()
- {
- return View();
- }
- [HttpPost]
- public ActionResult Create(SysUser sysUser)
- {
- db.SysUsers.Add(sysUser);
- db.SaveChanges();
- return RedirectToAction("Index");
- }
修改用户:
- //修改用户
- public ActionResult Edit(int id)
- {
- SysUser sysUser = db.SysUsers.Find(id);
- return View(sysUser);
- }
- [HttpPost]
- public ActionResult Edit(SysUser sysUser)
- {
- db.Entry(sysUser).State =EntityState.Modified;
- db.SaveChanges();
- return RedirectToAction("Index");
- }
删除用户:
- //删除用户
- public ActionResult Delete(int id)
- {
- SysUser sysUser = db.SysUsers.Find(id);
- return View(sysUser);
- }
- [HttpPost,ActionName("Delete")]
- public ActionResult DeleteConfirmed(int id)
- {
- SysUser sysUser = db.SysUsers.Find(id);
- db.SysUsers.Remove(sysUser);
- db.SaveChanges();
- return RedirectToAction("Index");
- }
NOTE
涉及到数据更新的地方都有两个同名的方法重载,一个用来显示[HttpGet],一个用来数据更新[HttpPost]
- 在右键方法名,生成相应的View
每个View的顶部需要添加一个声明
@modelMVCDemo.Models.SysUser
各个view的body中具体代码:
Create.cshtm
- <body>
- <div>
- <h2>Create</h2>
- @using (Html.BeginForm())
- {
- <div>
- @Html.LabelFor(model => model.UserName)
- @Html.EditorFor(model => model.UserName)
- </div>
- <div>
- @Html.LabelFor(model => model.Email)
- @Html.EditorFor(model => model.Email)
- </div>
- <div>
- @Html.LabelFor(model => model.Password)
- @Html.PasswordFor(model => model.Password)
- </div>
- <div>
- <inputtypeinputtype ="submit" value="Create" />
- </div>
- }
- <div>@Html.ActionLink("Back to List", "Index")</div>
- </div>
- </body>
Edit.cshtml
- <body>
- <div>
- <h2>Edit</h2>
- @using (Html.BeginForm())
- {
- @Html.HiddenFor(model => model.ID)
- <div>
- @Html.LabelFor(model => model.UserName)
- @Html.EditorFor(model => model.UserName)
- </div>
- <div>
- @Html.LabelFor(model => model.Email)
- @Html.EditorFor(model => model.Email)
- </div>
- <div>
- @Html.LabelFor(model => model.Password)
- @Html.PasswordFor(model => model.Password)
- </div>
- <div>
- <inputtypeinputtype ="submit" value="Save" />
- </div>
- }
- <div>@Html.ActionLink("Back to List", "Index")</div>
- </div>
- </body>
Delete.cshtml
- <body>
- <div>
- <h2>Delete</h2>
- <h3>Are you sure you want to delete this?</h3>
- <h4>User</h4>
- <dl>
- <dt>@Html.DisplayNameFor(model => model.UserName)</dt>
- <dd>@Html.DisplayFor(model => model.UserName)</dd>
- <dt>@Html.DisplayNameFor(model => model.Email)</dt>
- <dd>@Html.DisplayFor(model => model.Email)</dd>
- </dl>
- @using (Html.BeginForm())
- {
- <div>
- <inputtypeinputtype ="submit" value="Delete" />
- </div>
- }
- <div>
- @Html.ActionLink("Back to List", "Index")
- </div>
- </div>
- </body>
NOTE
针对上面这些代码,我们提一下其中用到的HtmlHelper, 主要有这么几个:
DisplayNameFor (model=>model.xxx)à 生成纯文本,显示xxx列名
DisplayFor (model=>model.xxx)à 生成纯文本,显示xxx列的内容
LableFor à 生成一个Lable标签
EditorFor à 生成一个text类型的input
PasswordFor à 类似于EditorFor, 隐藏文本内容
ActionLink à 生成一个<a>标签
BeginForm à 生成一个表单
NOTE
HtmlHelper是可以通过View的Html属性调用的方法(@Html.xxx), 可以类比成原来WebForm的服务器端控件, 后续文章会将分成几类, 归类进行介绍,这里先简单提一下做个铺垫。这块最好的学习方法是用浏览器打开相应的页面,View page source,查看生成的相应HTML代码。
Repository Pattern
最好再补充下Repository Pattern,为下篇文章重构代码做个铺垫。
Repository Pattern是一种设计模式,这个概念大家肯定经常听到。
"企业架构模式" 上的定义:
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
具体的做法:
先定义Interface, 通过定义接口确定数据访问类的功能需求, 接着实现该接口。
以对SysUser这张表的操作为例。
先建一个文件夹 Repositories, 在文件夹中新建一个接口IsysUserRepository
我们预先定义几个功能。
- namespace MVCDemo.Repositories
- {
- public interfaceISysUserRepository
- {
- //查询所有用户
- IQueryable<SysUser> SelectAll();
- //通过用户名查询用户
- SysUser SelectByName(string userName);
- //添加用户
- void Add(SysUser sysUser);
- //删除用户
- bool Delete(int id);
- }
- }
同样文件夹下新建类,继承接口,实现功能。
- namespace MVCDemo.Repositories
- {
- public classSysUserRepository : ISysUserRepository
- {
- protected AccountContext db =new AccountContext();
- //查询所有用户
- public IQueryable<SysUser> SelectAll()
- {
- return db.SysUsers;
- }
- //通过用户名查询用户
- public SysUser SelectByName(string userName)
- {
- return db.SysUsers.FirstOrDefault(u => u.UserName == userName);
- }
- //添加用户
- public void Add(SysUser sysUser)
- {
- db.SysUsers.Add(sysUser);
- db.SaveChanges();
- }
- //删除用户
- public bool Delete(int id)
- {
- var delSysUser=db.SysUsers.FirstOrDefault(u => u.ID == id);
- if (delSysUser !=null)
- {
- db.SysUsers.Remove(delSysUser);
- db.SaveChanges();
- returntrue;
- }
- else
- {
- returnfalse;
- }
- }
- }
- }
通过IsysUserRepository接口对象引用SysUserRepository类的实例来调用:
- ISysUserRepository ur=new SysUserRepository();
- var user=ur.xxx;
怎么样,平时听到的Repository Pattern实现起来就这么简单。
楼主提示 设计模式都来源于编程实践,只要掌握其中几个重要原则,GOF总结的设计模式都能自己推导出来,就类似于几何中的公理和定理的关系。大家工作中做个有心人,多思考,多总结。
总结
OK,到此为止,我们对常用的CRUD做了介绍。View, Controller之间都是通过传递Model来交互的。特别要提下下面这张图,通过navigation property实现SysUserà SysUserRoleà SysRole 多表间查询。
当然,这种做法还是有局限性的,后续文章中我们会介绍如何实现类似于之前SQL查询多个表,将多个表的查询结果,例如datatable直接传到view中来显示数据。
好了,今天就到这里。
转载自 三天不学习 :http://blog.csdn.net/mss359681091/article/details/52135855
- MVC5+EF6 入门完整教程四
- MVC5+EF6 入门完整教程四
- MVC5 + EF6 入门完整教程 四
- MVC5 + EF6 入门完整教程
- MVC5 + EF6 入门完整教程
- MVC5 + EF6 入门完整教程
- MVC5 + EF6 入门完整教程
- MVC5+EF6 入门完整教程八
- MVC5 + EF6 入门完整教程一
- MVC5 + EF6 入门完整教程二
- MVC5+EF6 入门完整教程五
- MVC5+EF6 入门完整教程六
- MVC5+EF6 入门完整教程七
- MVC5+EF6 入门完整教程八
- MVC5+EF6 入门完整教程九
- MVC5+EF6 入门完整教程十
- MVC5 + EF6 入门完整教程二
- MVC5+EF6 入门完整教程五
- springboot(十一):Spring boot中mongodb的使用
- vue2.0使用(2)
- 计算:RenderScript
- 软件测试的分类——按测试阶段分类
- java类的成员初始化顺序和初始化块知识
- MVC5 + EF6 入门完整教程 四
- ubuntu下安装QT5.7.1
- 文件描述符与文件指针
- InterruptedException+interrupt停止线程的疑惑
- 【web】HTTP状态返回码介绍,客户端请求服务器端,服务器返回状态码的含义介绍整理。
- delete和truncate的区别
- linux---常用压缩,解压缩命令
- Shell判断字符串包含关系的几种方法
- Dataquest学习总结[4]