本篇是第一阶段的完结篇。

学完这篇后,你应该可以利用MVC进行完整项目的开发了。

本篇主要讲述多表关联数据的更新,以及如何使用原生SQL。

文章提纲

  • 多表关联数据更新
  • 如何使用原生SQL
  • 总结

多表关联数据更新

我们在第四篇文章已经讲过数据的更新了,不过那个是针对单表结构的更新。

这次我们讲下使用EF进行关联数据的更新。

关联数据更新有两种情况:

1.一对多

2.多对多

第一种情况关联表有主外键关联,只要简单的更新外键值就可以了(相当于更新单表),我们主要讲解第二种多对多的情况。

使用之前很熟悉的模型:

我们定义一个场景:

一个用户可以有任意多个角色,一个角色可以有任意多个用户。

我们接下来完成下面操作:

编辑某个用户时,显示该用户的角色进行编辑。

即 更新某个用户(SysUser表)及其相关的角色(SysUserRole表)。

详细步骤:

1.先添加一个ViewModel, 用来表示角色是否分配给某个用户。

2.打开UserRoleController,添加一个Edit的Action用来显示编辑页面。

有两点说明一下:

a.我们沿用上一篇文章的模型,多了一个SysDepartment,实际模型如下:

b.PopulateAssigenedRoleData将特定用户下选中的角色标记出来。

3.打开Views\UserRole\Index.cshtml, 增加一个编辑按钮

4.再根据Edit Action自动生成Edit View

修改相关内容,主要是两点:

a.部门

b.角色

角色是通过一组checkbox来显示的。

Checkbox显示数据库中所有角色,已分配给用户的会显示选中状态。

通过勾选checkbox的方式来实现用户角色的更新。

说明

角色少这样弄没问题,如果多的话经典的做法,可以用两个listbox,中间用箭头将左右两边的选项移动。本篇文章主要说明关联表的更新,后续文章我们会提供更好的做法的示例。

运行下Index页面。

进入编辑页面。

这样编辑的显示功能就已经完成了。

可以看到,用一组checkbox表示roles是否选中。

5.最后再完成HttpPost的Edit功能。

首先更新SysUser表:

用model binder中的值更新entity: userToUpdate.

可以看到,我们使用了白名单指定数据库中需要更新的字段。

TryUpdateModel(userToUpdate,"",

new string[] {"LoginName","Email","Password","CreateDate","SysDepartmentID"})

再更新SysUserRole表:

将数据库中值和编辑后的值进行比对,基本逻辑是:

如果被选中了,原来没有的要添加;

如果没被选中,原来有的要删除。

UpdateUserRoles(selectedRoles, userToUpdate);

注意在UpdateUserRoles里,我新建了一个连接

using (AccountContext db2=new AccountContext())

如果用之前的db会报如下错误:

已有打开的与此 Command 相关联的 DataReader,必须首先将它关闭。

重新运行下Index, 如下一组图,这时我们看到角色编辑已经起作用了。

至此,多表更新的示例就介绍到这,其他情况相信你可以举一反三自己推导出来做法。

使用原生SQL

使用EF的一个优点就是自动帮我们生成SQL,这在常规情况下很方便,但有些情况下用EF却不适合。

例如我们上面更新SysUserRole这张表时,每次增减一条数据,要循环很多次。

另外还有些特别复杂的语句,利用EF很难生成。

EF提供一组方法用来执行原生的SQL.

有以下三种:

1.DbSet.SqlQuery

2.Database.SqlQuery

3.Database.ExecuteSqlCommand

这三种有啥区别呢?我们来看例子。

对三种形式我们各举一例。

例子1:DbSet.SqlQuery查询并返回Entities

我们打开Controllers\AccountController.cs做实验

找到Details方法

将注释的部分改成方框部分即可。

方框中的和注释掉的内容SysUser sysUser=db.SysUsers.Find(id)完全一样。

前端显示效果不变:

注意两点:

1.构造带参数的SQL语句(养成好习惯,防止SQL注入,总是用带参数的SQL语句)

2.此处使用的是DbSet<TEntity>执行SQL方法,返回的直接是Entity, 和LINQ查询一样。如果暂时不熟悉LINQ,用这种方法替换(作为一个过渡),可以让你快速的使用起新框架。

这种情况有一些缺陷,例如

SELECT LoginName as UserName,* FROM [dbo].[SysUser] WHERE ID=@id

大家可以看到我添加了LoginName as UserName,这是因为Model中用了Column Attribute,数据库中存的字段是LoginName

这样我如果不转换,model就会找不到匹配的字段而出错,而如果用db.SysUsers.Find(id) 就可以智能转换。

例子2 Database.SqlQuery 返回其他类型

string query = "select loginName from SysUser";

var names=db.Database.SqlQuery<string>( query).ToList();

以上会返回一个System.Collections.Generic.List<string>类型。

这种方式和第一种情况最大的区别就是返回non-entity 类型。

我们可以根据需要,自己构建需要的类型。

我们也可以自定义一个entity type让它返回,例如类似我们上一个例子:

SysUser sysUser = db. Database.SqlQuery(query, paras).SingleOrDefault();

这样也可以返回entity, 但要注意,这种方式将不会被context track, 返回后就没关系了,如果我们在View中用类似于Model.XXX导航属性获取其他关联数据就会报错。例如@foreach (var item in Model.SysUserRoles),这种情况下会报Model为null的错误。

例子3:Database.ExecuteSqlCommand执行更新语句

最后一个是更新的,直接看示例就明白了:

context.Database.ExecuteSqlCommand("UPDATE dbo.Posts SET Rating = 5 WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));

最后提下执行存储过程,也类似,我就不多说了,如下MSDN(https://msdn.microsoft.com/en-us/data/jj592907)截图。

原生SQL使用总结

原生SQL执行查询:

需要返回实体模型,使用DbSet.SqlQuery (context会跟踪,等效于LINQ方式)

需要返回其他类型,使用Database.SqlQuery

原生SQL执行更新:

使用Database.ExecuteSqlCommand

至此,本系列文章的第一阶段(1~10)就结束了,下一阶段再见。

感谢支持,祝学习进步!

P.S. 方便大家观看,列出系列文章地址:

  • MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用
  • MVC5+EF6 入门完整教程10:多对多关联表更新&使用原生SQL@20150521
  • MVC5+EF6 入门完整教程9:多表数据加载@20150212
  • MVC5+EF6 入门完整教程8 :不丢失数据进行数据库结构升级 @20141215
  • MVC5+EF6 入门完整教程7 :排序过滤分页 @20141201
  • MVC5+EF6 入门完整教程6 :分部视图(Partial View) @20141117
  • MVC5+EF6 入门完整教程5 :UI的一些改造 @20141113
  • MVC5+EF6 入门完整教程4 :EF基本的CRUD @20141104
  • MVC5+EF6 入门完整教程3 :EF完整开发流程 @20141027
  • MVC5+EF6 入门完整教程2 :从前端UI开始 @20141021
  • MVC5+EF6 入门完整教程1 :从0开始

EF多表关联数据更新相关推荐

  1. MySQL 两张表关联更新(用一个表的数据更新另一个表的数据)两个表使用条件从另外一个表获取数据更新本表

    MySQL 两张表关联更新(用一个表的数据更新另一个表的数据)两个表使用条件从另外一个表获取数据更新本表 有两张表,info1, info2 . info1: info2: 方式一:要用info2中的 ...

  2. ef oracle 批量更新慢_详解Oracle中多表关联批量插入、批量更新与批量删除

    概述 今天主要介绍一下Oracle数据库中多表关联批量插入.多表关联批量更新和多表关联批量删除.下面用实验来理解下~ 一.创建必须的表和序列语句 --创建部门表 dept:CREATE TABLE d ...

  3. 大主子表关联的性能优化方法

    [摘要] 主子表是数据库最常见的关联关系之一,最典型的包括合同和合同条款.订单和订单明细.保险保单和保单明细.银行账户和账户流水.电商用户和订单.电信账户和计费清单或流量详单.当主子表的数据量较大时, ...

  4. Oracle\MS SQL Server的数据库多表关联更新UPDATE与多表更新

    一条Update更新语句是不能更新多张表的,除非使用触发器隐含更新.而表的更新操作中,在很多情况下需要在表达式中引用要更新的表以外的数据.我们先来讨论根据其他表数据更新你要更新的表 一.MS    S ...

  5. HubbleDotNet 开源全文搜索数据库项目--为数据库现有表或视图建立全文索引(三) 多表关联全文索引模式...

    关系型数据库中,多表关联是很常见的事情,HubbleDotNet 可以对部分情况的多表关联形式建立关联的全文索引,这样用户就不需要专门建一个大表 来解决多表关联时的全文索引问题. 下面以 为数据库现有 ...

  6. mybatisplus多表关联查询_Excel、MySQL、PowerBI、Python来告诉你 数据关联与联合不一样

    阅读提示 本内容为日常频繁使用的数据处理操作,不涉及底层技术问题,烦请爱钻牛角的杠精绕行. 本内容尽量简单直白.步骤详细,适合数据分析入门.特别喜欢技术语言的大佬们,可自行跳过. 在上一篇:Pytho ...

  7. sql语句语法多表关联_SQL Delete语句-如何删除行或表,语法示例

    sql语句语法多表关联 To delete a record in a table you use the  DELETE  statement. 要删除表中的记录,请使用DELETE语句. Be c ...

  8. MySQL百万级、千万级数据多表关联SQL语句调优

    本文不涉及复杂的底层数据结构,通过explain解释SQL,并根据可能出现的情况,来做具体的优化,使百万级.千万级数据表关联查询第一页结果能在2秒内完成(真实业务告警系统优化结果). 希望读者能够理解 ...

  9. mysql面试关联查询语句_MySQL百万级、千万级数据多表关联SQL语句调优

    作者:成金之路 www.cnblogs.com/uttu/p/6384541.html 本文不涉及复杂的底层数据结构,通过explain解释SQL,并根据可能出现的情况,来做具体的优化,使百万级.千万 ...

  10. 使用外部表关联MySQL数据到Oracle

    因为业务需要,有个临时的活动需要DBA来支持一些数据业务,问题来了,需要从MySQL端同步一部分数据到Oracle端,然后从Oracle端匹配查到相应的数据返回给MySQL,至于原因,也是不同的业务系 ...

最新文章

  1. ionic之点击放大图片
  2. Android关于绘图中Shader 的效果(中级)
  3. 【转】linux tar.gz zip 解压缩 压缩命令
  4. fatal error LNK1103: debugging information corrupt; recompile module
  5. 【Lintcode】018.Subsets II
  6. 模拟电子技术不挂科学习笔记3(放大电路的分析方法)
  7. 一些值得注意的算法题——双指针
  8. NUC1776 Tiling Up Blocks【二维最长上升子序列+DP】
  9. Day 1 MySQL数据库
  10. java英雄联盟战斗力题目,lol:英雄联盟宇宙的顶尖战力,那些强大的飞升者们...
  11. DDOS防火墙新一代操作思路与进阶应用方法浅析
  12. 学习太极创客 — ESP8226 (一)
  13. 骨骼动画原理学习笔记
  14. PCB设计时如何选择合适的叠层方案
  15. Games101学习笔记(一)
  16. linux网站ip访问量查询,如何统计网站每天PV和IP访问量排行
  17. randint和randrange的区别
  18. 前端JavaScript+HTML
  19. linux下如何挂载磁盘阵列
  20. 2020年笔记本电脑计算机专业,适合女生用的笔记本电脑排名2020

热门文章

  1. Kickoff(上路了)
  2. 克拉克误差网格分析程序(Performs Clarke Error Grid Analysis)
  3. 东八区转为0时区_世界时间与北京时间怎么转换,世界标准(0时差)时间以哪个国家为准?...
  4. Adobe Photoshop 7.0.1 简体中文版注册码
  5. 读《卧底经济学》有感
  6. php圆周长怎么求,圆的周长怎么求 公式是什么
  7. centos7 默认中文字体_centos7安装中文宋体
  8. 第三阶段应用层——1.1 数码相册—软件框架
  9. 关于Android学习的三个终极问题
  10. iOS:直播动态评论和点赞效果