admin 管理员组文章数量: 1184232
2023年12月18日发(作者:c2059 语法错误)
MVC3+EF4.1学习系列(六)-----导航属性数据更新的处理
Admin
2011年8月1日 名人名言:书,这是这一代人对另一代人精神上的遗言,这是将死的老人对刚刚开始生活的青年人的忠告,这是准备去休息的哨兵对前来代替他的岗位的哨兵的命令。——赫尔岑
文章索引和简介
通过上一篇的学习 我们已经知道怎么查询关系 这篇就来说说怎么导航属性数据更新时的处理 以及EF又会为我们生成哪些SQL~
老规矩 先看下今天的图
添加和修改页面基本就是这样
这节的内容相对简单~~
主要就是讲 一对一 一对多 多对多时的增删改 以及MVC的一些小东西
一. 一对多的的处理
看第一张图 院系和课程是一对多的关系
1.添加
一对多的添加非常简单 遇到一对多的情况 我们一般考虑dropdownlist来展示 只要把这个展示出来就容易了
mvc绑定dropdownlist 一般是 控制器用 viewstate存一个SelectList 或者viewbag 然后视图绑定 上代码
课程添加控制器
public ActionResult Create()
{ PopulateDepartmentsDropDownList(); return View(); }
// // POST: /Course/Create [HttpPost] public ActionResult Create(Course course) { try { // TODO: Add
logic here if (d)
{ (course); anges();
// PopulateDepartmentsDropDownList(mentID); }
return RedirectToAction("Index"); } catch
{ elError("", "Unable to save changes. Try again, and
if the problem persists, see your system administrator."); return View(); } } ///
/// /// 选择的项 private void
PopulateDepartmentsDropDownList(object ed = null) { var
departmentsQuery = d in ments orderby
d; mentID =
new SelectList(departmentsQuery, "DepartmentID", "Name", ed); }
可以看到 非常简单下面是视图的
视图
@model @{ = "Create"; Layout =
"~/Views/Shared/_";}
Create
@using(orm()) { @tionSummary(true)
}
视图的核心其实就这句
wnList("DepartmentID","请选择")
DepartmentID 对应 你的viewbag 就能让他们对应上去了 就这么简单神奇~~ 由于生成的html name 为 DepartmentID 当你保存的时候 通过ModelBinder 会自动对应到实体类上 直接保存即可 生成的SQL插入语句也简单 而且是参数化的~
exec s p_executesql N"" [dbo].[Course]([CourseID], [Title], [Credits], [DepartmentID])values
(@0, @1, @2, @3)"",N""@0 int,@1 nvarchar(50),@2 int,@3 int"",@0=4444,@1=N""试试插入"",@2=4,@3=1
2.修改
这个没啥好说的了~~ 基本和添加一样
修改控制器
public ActionResult Edit(int id) { Course course = (id);
PopulateDepartmentsDropDownList(mentID); return View(course); } // // POST: /Course/Edit/5 [HttpPost]
public ActionResult Edit(Course course) { try
{ if (d)
{ (course).State = ed;
anges(); return RedirectToAction("Index"); } } catch (DataException)
{ //Log the error (add a variable name after DataException)
elError("", "Unable to save changes. Try again, and if the problem persists,
see your system administrator."); }
PopulateDepartmentsDropDownList(mentID); return View(course); }
生成的SQL语句如下
exec s p_executesql N"" [dbo].[Course]set [Title] = @0, [Credits] = @1, [DepartmentID] = @2where ([CourseID] = @3)"",N""@0 nvarchar(50),@1 int,@2 int,@3 int"",@0=N""试试插入"",@1=4,@2=2,@3=4444
这有个问题 就是把每个字段都做了更新 而我们实际上只更新了一个 如果能按需更新改多好 dudu给了我们好的思路 可以参考下 -----文章连接
3.删除
这个简单....没啥好说的了 具体参考第二篇 简单的增删改查~~
二.一对一和多对多
一对多比较简单 因为涉及的都是一张表里的东西 所以没什么难的 而一对一,多对多 则是处理 多张表的情况 所以这里重点说下这部分~~
先看第二个图 分析下关系 这是修改老师的信息 跟他关联的有一对一的地址 和多对多的课程 也就是说 当我们插入一条记录时
应该插入三张表 教师表 办公地址表 和 教师课程关系表 那让我们来印证下吧
1.添加
首先 我们要先把添加页面显示出来 先来说下 下面那个复选框选择课程 控制器很简单
就是读取出来所有课程存放到viewbag里即可
public ActionResult Create() { Course = (); return View(); }
视图的显示 有两种方法 一种是原文提供的
添加一个viewmodel 专门存放课程 以及是否选中 然后通过如下代码实现三列换行
原文的方法
| name="edCourses" value="@ID" @((ed ? "checked="checked"" : "")) /> @ID @: @ @: | } @:
个人觉得麻烦了些 这里我说下我的方法
Builder("
name=""edCourses""/>"+list[i].Title+" | "); } ("
这里要说的就是 如果不使用这个 直接输入 则会把
好了 添加页面有了 现在就是添加了
添加
[HttpPost] public ActionResult Create(Instructor Model, string[] edCourses)
{ try { // TODO: Add logic here
if (d) { s = new
List
{
{
(item);
if
foreach (var item in ())
(ns(ng()))
} }
(Model); anges(); } return RedirectToAction("Index"); } catch
{ return View(); } }
这里提下 第二个参数 就是我们选中的checkbox 的value 的集合 这个参数的名字 与
checkbox名字的name一样
然后我们遍历所有的课程 把符合条件的加入进来 我选了一个 让我们看下EF为我们生成的SQL
exec s p_executesql N"" [dbo].[Instructor]([LastName], [FirstName], [HireDate])values (@0, @1, @2) [InstructorID] [dbo].[Instructor]where @@ROWCOUNT > 0 and [InstructorID]
= scope_identity()"",N""@0 nvarchar(50),@1 nvarchar(50),@2 datetime"",@0=N""W"",
@1=N""LF"",@2=""02 3 2011 12:00:00:000AM""exec s p_executesql N""
[dbo].[CourseInstructor]([CourseID], [InstructorID])values (@0, @1)"",N""@0 int,@1 int"",@0=2042,@1=10exec s p_executesql N"" [dbo].[OfficeAssignment]([InstructorID],
[Location])values (@0, @1)"",N""@0 int,@1 nvarchar(50)"",@0=10,@1=N""天朝""
看 确实是生成了三条SQL语句 符合我们的要求 而我们的代码 却写了很少 就轻松完成了添加~~
2.修改
修改要比添加麻烦 首先显示视图时 要显示哪些被选中了 还有就是修改时 要在关系表里删除原来的 课程教师关系 还要添加新的进去
如何让EF帮我们完成这一对一 多对多的复杂的 三张表之间的关系处理呢
还是先从视图开始 先解决让以前被选中的显示出来
public ActionResult Edit(int id) { Course =
(); Instructor model= e(i =>
s).Include(i => Assignment).Where(i => ctorID == id).SingleOrDefault(); return View(model); }
先把要修改的这条加载出来返回给视图 用贪婪加载 把地点和课程都加载出来
修改视图
Builder("
name=""edCourses""/>"+list[i].Title+" | "); } ("
在视图上加上判断 遍历到的这个课程 是否在选中的课程里 如果在 则加上选中属性
string IsSelect = ; if (ns(list[i]))
{ IsSelect = "checked=""checked"""; }
这样就解决了视图修改时的显示问题了 下面是点击修改时 让我们先大概想想 有哪些操作
1.修改 教师表信息
2.修改 地址表信息
3. 删除以前的课程关系表 和添加新的课程关系表记录
这里比较负责的是第三部 我们来想想怎么做 现在 我们能知道 我们新选择了哪些 和
以前选择了哪些 比如 新选择的是 {1,2,3} 这次选的是 {3,4,5} 那么我们应该
删除{4,5} 添加{1,2} 即可 这其实就转换为一个简单的算法题了~~ 原文给出了一种方法
我自己也写了一种 大家可以比较下看~先上原文的
原文修改核心代码
private void UpdateInstructorCourses(string[] edCourses, Instructor instructorToUpdate){ if
(edCourses == null) { s = new List
return; } var edCoursesHS = new HashSet
instructorCourses = new HashSet
ID)); foreach (var course in s) { if (ns(ng())) { if (!ns(ID)) { (course); } } else { if
(ns(ID))
{
(course); } } }}
原文利用HashSet 不能存重复项 实现 不过判断逻辑多了些 但效率应该高 hashset 散列算法
下面是我的
private void UpdateInstructorCourses(string[] edCourses, Instructor instructor)
{ if (edCourses == null) { s =
new List
string[] beforeSelect=(i => ng()).ToArray();//得到以前选择的 (edCourses).ToList().ForEach(n =>
((32(n))));
(beforeSelect).ToList().ForEach(n => ((32(n)))); }
这里 参数edCourses 为现在选中的项 利用linq 内置的方法 Except取出差集 然后
ForEach遍历移除和添加 一句话搞定 但是效率估计不会太高~~
下面是完整的修改方法
完整修改方法
[HttpPost] public ActionResult Edit(int id, FormCollection collection, string[]
edCourses) { try { // TODO: Add logic
here var instructor = e(i => s).Where(i =>
ctorID == id).SingleOrDefault(); UpdateModel(instructor, "", null,
new string[] {"Courses"}); UpdateInstructorCourses(edCourses, instructor);
if (OrWhiteSpace(on))
{ Assignment = null; }
(instructor).State = ed; anges();
return RedirectToAction("Index"); } catch
{ return View(); } } private void
UpdateInstructorCourses(string[] edCourses, Instructor instructor) { if
(edCourses == null) { s = new List
string[] beforeSelect=(i => ng()).ToArray();//得到以前选择的 (edCourses).ToList().ForEach(n =>
((32(n))));
(beforeSelect).ToList().ForEach(n => ((32(n)))); }
好了 让我们来看下执行的SQL
exec s p_executesql N"" [dbo].[Instructor]set [LastName] = @0, [FirstName] = @1, [HireDate]
= @2where ([InstructorID] = @3)"",N""@0 nvarchar(50),@1 nvarchar(50),@2 datetime,@3 int"",@0=N""W"",@1=N""LF"",@2=""02 3 2011 12:00:00:000AM"",@3=10exec s
p_executesql N"" [dbo].[OfficeAssignment]set [Location] = @0where ([InstructorID] = @1)"",N""@0 nvarchar(50),@1 int"",@0=N""超"",@1=10exec s p_executesql N""
[dbo].[CourseInstructor]where (([CourseID] = @0) and ([InstructorID] = @1))"",N""@0 int,@1 int"",@0=2042,@1=10exec s p_executesql N"" [dbo].[CourseInstructor]([CourseID],
[InstructorID])values (@0, @1)"",N""@0 int,@1 int"",@0=0,@1=10
看 和我们想要的效果一样~~
3.删除
简单的说下删除, 当我们删除一条数据时 直接看生成的SQL语句 预计应该是 要删3个
表
exec s p_executesql N"" [dbo].[CourseInstructor]([CourseID], [InstructorID])values (@0,
@1)"",N""@0 int,@1 int"",@0=0,@1=10exec s p_executesql N""
[dbo].[OfficeAssignment]where ([InstructorID] = @0)"",N""@0 int"",@0=10
结果是删除了 2个表的 一对一的删除了 可是多对多的为什么没删除 这其实是一个简单的数据库知识了~~
EF为我们创建数据库时 这个删除规则是层叠 就是级联删除 所以这个关系表的就会被直接删除了
三.总结
导航属性的更新操作等 结束了 现在EF的已经基本操作已经结束了 下一节讲EF处理并发的策略
版权声明:本文标题:MVC3+EF4.1学习系列(六)---导航属性数据更新的处理 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1702869143a433933.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
更多相关文章
告别多系统烦恼:如何在Win10下安全卸载Ubuntu和Linux引导
本文环境,win10+Ubuntu。 先删除引导再操作卷因为之前想学习Linux,所以就在win10上又安装了Ubuntu,现在不想搞了,再加上win10空间不太够用了,就想删除linux系统。话不多说,直接开
_pibkwl.sys 打扰到你的工作流程?马上用这技巧扫除障碍!
一、常规解决办法:1,注消或重启电脑,然后再试着删除。2,进入“安全模式删除”。3,在纯DOS命令行下使用DEL,DELTREE和RD命令将其删除。4,如果是文件夹中有比较多的子目录或文件而导致无法删除,
'鬼影'在D盘?揭秘怎么处理那些粘性十足的Flash文件!
在Windows系统中,难免会遇到用常规方法无法删除文件的情况。 1:重新启动电脑,再试着删除一次。这方法虽简单但往往很奏效。2:命令行删除法按Win+R键调出“运行”对话框,输入“C
快速技巧:教你快速删除Wi-Fi连接后的数字尾巴
无线名称后边多了一个数字后缀,本身不影响正常使用网络 先断开网络连接,然后Win+R打开运行框,输入regedit打开注册表编辑器,按照以下路径打开: HKEY_LOCAL_MACHINESOFTWAREMicro
优化电脑:从删除Adobe Flash Player文件开始的小窍门
删除7天以前的文件@echo offecho dt=date()-7>%temp%tmp.vbsecho s=right(year(dt),2) ^& right("0" ^&
一网打尽!彻底清理无法删除的Adobe Flash Player残留
对于删除不掉的文件可以用以下方法删除:1.开机时按住F8键不放,进入安全模式下删除该文件(我试过,一般都可以删除);2.改变该文件的属性后再删:右键点击该文件-属性-取消最下方的“只读文件”的勾选;
详解 "Apple Mobile Device Support" 的去留之谜——卸载前后的影响解读。
想要卸载Apple Mobile Device Support但是到最后就回滚导致无法卸载也无法更新,此时我们有两种目的:一是仅仅因为看着不爽想卸载;二是想安装最新版iTunes。这里仅仅给出我的经历的思路,不是普适的,我是找了很久都
回归经典:XP系统下将IE8转换至IE7,优化Adobe Flash Player体验
由于网站开发的需要,第一时间安装了Internet Explorer 8 Beta,但因为兼容性的问题,又不得不恢复到IE 7,但是在卸载的时候发现,在我的“控制面板”的“添加删除程序”中并没有直接提供卸载选项。 于是
一站式解决,友盟社会化分享iOS组件让你的App瞬间爆棚!
> 1. 分享流程介绍 1.1 下载并安装SDK 安装SDK可以采用CocoaPods和手动下载两种方式,选择下面其中一种来集成即可 1.1.1 使用CocoaPods集成 在Podfil
从头到尾提速:.NET 4.0中Mscoree和Mscoreei,优化应用启动时间
一次 Reboot=975 年 在开始本文之前先做一个小调查:有多少朋友喜欢Reboot?答案A:我喜欢,每天都要Reboot N次。答案B:我不喜欢,最好一个星期都不要Reboot。如
Flash中心助力,一招解决IE浏览器主页故障,体验顺畅浏览
IE主页的修改分为俩类:IE和IE的快捷键修改。 1. 解决办法1: ①在Windows 启动后,点击“开始”→“运行”菜单项,在“打开”栏中键入regedit,然后按“确定”键; ②展开注册表到HKEY_LO
visual Studio改变EXE的图标_visual studio2015修改程序图标
当你写了很多很多的exe,发现他们都是一个样子 哦,头都大了,写了那么多的代码,作为一个软件的maker,为自己的孩子都不能邮件漂亮的衣服,失败。为了他们,接下来花5分钟就能改变你的EXE。 首先在你的项目(不论是
IE主页修复指南
IE主页的修改分为俩类:IE和IE的快捷键修改。 1. 解决办法1: ①在Windows 启动后,点击“开始”→“运行”菜单项,在“打开”栏中键入regedit,然后按“确定”键; ②展开注册表到HKEY_LO
彻底删除oracle的垃圾表_删除oracle 垃圾表
经常使用 10g,我们可以发现以前删除的表在数据库中出现了特别多的垃圾表,如下例:BINjR8PK5HhrrgMK8KmgQ9nw==这一类的表通常无法删除,并且无法用"delete"删除,这种情况的出
彻底清除U盘Autorun.inf病毒的自动化脚本
简介:本文介绍了一个自动化脚本,专门用于删除利用Autorun.inf文件自动运行的病毒。通过一系列详细的步骤,包括断开U盘连接、显示隐藏文件、删除Autorun.inf文件、检查注册表以及全面扫描修复等,帮助用户清除病毒并提供防护建
无法通过控制面板中的“添加删除程序”来添加删除程序的解决方法_无法添加和或删除您所请求的产品
问: 我的Windows XP系统不知是什么原因,现在无法通过控制面板中的“添加删除程序”来添加删除程序,每当打开时,系统弹出“本次操作由于计算机限制而被取消,请与管理员联系”,不知如何解决? 答:可以通过修改注册表来解除“
添加删除程序中的无效信息_无效的软件信息
系统中“添加删除程序”里面的信息全部储存于注册表HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstall下面,打开注册表编辑器,找到不需要软件的卸载信
彻底玩转OpenWRT:USB无线网卡安装与优化指南
说明要完成网线网卡的驱动需要在内核中添加驱动,同时还需要将固件放入rootfs中正确的位置,如果需要固件的话。 内核驱动添加 因为内核中对常规的USB网卡均支持,所以直接添加即可, 例如下面是
解锁OpenWRT新功能:USB无线网卡的添加教程
说明要完成网线网卡的驱动需要在内核中添加驱动,同时还需要将固件放入rootfs中正确的位置,如果需要固件的话。 内核驱动添加 因为内核中对常规的USB网卡均支持,所以直接添加即可, 例如下面是
发表评论