通过上一篇的学习 我们已经知道怎么查询关系 这篇就来说说怎么导航属性数据更新时的处理 以及EF又会为我们生成哪些SQL~

老规矩 先看下今天的图

添加和修改页面基本就是这样

这节的内容相对简单~~

主要就是讲  一对一 一对多 多对多时的增删改 以及MVC的一些小东西

一. 一对多的的处理

看第一张图   院系和课程是一对多的关系

1.添加

一对多的添加非常简单  遇到一对多的情况  我们一般考虑dropdownlist来展示 只要把这个展示出来就容易了

mvc绑定dropdownlist 一般是 控制器用 viewstate存一个SelectList  或者viewbag  然后视图绑定 上代码

课程添加控制器

可以看到 非常简单下面是视图的

视图

视图的核心其实就这句

Html.DropDownList("DepartmentID","请选择")
DepartmentID 对应 你的viewbag  就能让他们对应上去了 就这么简单神奇~~  由于生成的html  name 为 DepartmentID 当你保存的时候 通过ModelBinder  
会自动对应到实体类上 直接保存即可
生成的SQL插入语句也简单 而且是参数化的~
exec sp_executesql N'insert [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.修改

这个没啥好说的了~~ 基本和添加一样

修改控制器

生成的SQL语句如下

exec sp_executesql N'update [dbo].[Course]
set [Title] = @0, [Credits] = @1, [DepartmentID] = @2
where ([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()
{
ViewBag.SelectCourse = db.Courses.ToList(); return View();
}

视图的显示 有两种方法  一种是原文提供的添加一个viewmodel  专门存放课程 以及是否选中  然后通过如下代码实现三列换行

原文的方法

个人觉得麻烦了些  这里我说下我的方法

   <div class="editor-field">
@{
System.Text.StringBuilder sb = new System.Text.StringBuilder("<table style='width:100%'><tr>");
List<ContosoUniversity.Models.Course> list= ViewBag.SelectCourse as List<ContosoUniversity.Models.Course>;
for (int i = 0; i < list.Count; i++)
{
if (i!=0&&i % 3 == 0)
{
sb.Append("</tr><tr>");
}
sb.Append("<td><input type='checkbox' value='"+list[i].CourseID+"' name='selectedCourses'/>"+list[i].Title+"</td>");
}
sb.Append("</tr></table> ");
}
@MvcHtmlString.Create(sb.ToString())
</div>

这里要说的就是 MvcHtmlString.Create   如果不使用这个 直接输入  则会把<tr><td> 这些也直接输入出来 而不是转换成HTML   记住,如果想生成想要的结果 请使用MvcHtmlString.Create

好了 添加页面有了 现在就是添加了

添加

这里提下 第二个参数 就是我们选中的checkbox 的value 的集合   这个参数的名字 与 checkbox名字的name一样

然后我们遍历所有的课程  把符合条件的加入进来 我选了一个  让我们看下EF为我们生成的SQL

exec sp_executesql N'insert [dbo].[Instructor]([LastName], [FirstName], [HireDate])
values (@0, @1, @2)
select [InstructorID]
from [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 sp_executesql N'insert [dbo].[CourseInstructor]([CourseID], [InstructorID])
values (@0, @1)
',N'@0 int,@1 int',@0=2042,@1=10 exec sp_executesql N'insert [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)
{
ViewBag.SelectCourse = db.Courses.ToList();
Instructor model= db.Instructors.Include(i => i.Courses).Include(i => i.OfficeAssignment).Where(i => i.InstructorID == id).SingleOrDefault();
return View(model);
}

先把要修改的这条加载出来返回给视图   用贪婪加载 把地点和课程都加载出来

修改视图

在视图上加上判断 遍历到的这个课程 是否在选中的课程里 如果在 则加上选中属性

 string IsSelect = string.Empty;
if (Model.Courses.Contains(list[i]))
{
IsSelect = "checked='checked'";
}

这样就解决了视图修改时的显示问题了 下面是点击修改时  让我们先大概想想 有哪些操作

1.修改 教师表信息

2.修改 地址表信息

3. 删除以前的课程关系表  和添加新的课程关系表记录

这里比较负责的是第三部  我们来想想怎么做 现在 我们能知道 我们新选择了哪些  和 以前选择了哪些   比如 新选择的是 {1,2,3}  这次选的是 {3,4,5} 那么我们应该

删除{4,5}  添加{1,2} 即可 这其实就转换为一个简单的算法题了~~ 原文给出了一种方法  我自己也写了一种  大家可以比较下看~先上原文的

原文修改核心代码

原文利用HashSet 不能存重复项 实现  不过判断逻辑多了些 但效率应该高  hashset 散列算法

下面是我的

     private void UpdateInstructorCourses(string[] selectedCourses, Instructor instructor)
{
if (selectedCourses == null)
{
instructor.Courses = new List<Course>();
return;
}
//思路 比较以前选择的和现在选择的 先取出他们的差集 那么这部分就是可以删除的项 和添加的部分
string[] beforeSelect=instructor.Courses.Select(i => i.CourseID.ToString()).ToArray();//得到以前选择的
beforeSelect.Except(selectedCourses).ToList().ForEach(n => instructor.Courses.Remove(db.Courses.Find(Convert.ToInt32(n))));
selectedCourses.Except(beforeSelect).ToList().ForEach(n => instructor.Courses.Add(db.Courses.Find(Convert.ToInt32(n))));
}

这里 参数selectedCourses 为现在选中的项   利用linq 内置的方法 Except取出差集  然后 ForEach遍历移除和添加   一句话搞定  但是效率估计不会太高~~

下面是完整的修改方法

完整修改方法

好了 让我们来看下执行的SQL

exec sp_executesql N'update [dbo].[Instructor]
set [LastName] = @0, [FirstName] = @1, [HireDate] = @2
where ([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=10 exec sp_executesql N'update [dbo].[OfficeAssignment]
set [Location] = @0
where ([InstructorID] = @1)
',N'@0 nvarchar(50),@1 int',@0=N'超',@1=10 exec sp_executesql N'delete [dbo].[CourseInstructor]
where (([CourseID] = @0) and ([InstructorID] = @1))',N'@0 int,@1 int',@0=2042,@1=10
exec sp_executesql N'insert [dbo].[CourseInstructor]([CourseID], [InstructorID])
values (@0, @1)
',N'@0 int,@1 int',@0=0,@1=10

看 和我们想要的效果一样~~

3.删除

简单的说下删除, 当我们删除一条数据时 直接看生成的SQL语句  预计应该是 要删3个表

exec sp_executesql N'insert [dbo].[CourseInstructor]([CourseID], [InstructorID])
values (@0, @1)
',N'@0 int,@1 int',@0=0,@1=10 exec sp_executesql N'delete [dbo].[OfficeAssignment]
where ([InstructorID] = @0)',N'@0 int',@0=10

结果是删除了 2个表的  一对一的删除了  可是多对多的为什么没删除 这其实是一个简单的数据库知识了~~

EF为我们创建数据库时  这个删除规则是层叠  就是级联删除  所以这个关系表的就会被直接删除了

三.总结

导航属性的更新操作等 结束了   现在EF的已经基本操作已经结束了  下一节讲EF处理并发的策略

MVC3+EF4.1学习系列(六)-----导航属性数据更新的处理的更多相关文章

  1. MVC3+EF4.1学习系列(五)----- EF查找导航属性的几种方式

    文章索引和简介 通过上一篇的学习 我们把demo的各种关系终于搭建里起来 以及处理好了如何映射到数据库等问题 但是 只是搭建好了关系 问题还远没有解决 这篇就来写如何查找导航属性 和查找导航属性的几种 ...

  2. MVC3+EF4.1学习系列(一)-------创建EF4.1 code first的第一个实例

    基于EF4.1 code first 简单的CRUD  园子中已经有很多了 ~~ 真不想再写这个了 可是为了做一个完整的小demo 从开始 到后面的一些简单重构 还是决定认真把这个写出来 争取写些别人 ...

  3. MVC3+EF4.1学习系列(二)-------基础的增删改查和持久对象的生命周期变化

    上篇文章中 我们已经创建了EF4.1基于code first的例子  有了数据库 并初始化了一些数据  今天这里写基础的增删改查和持久对象的生命周期变化 学习下原文先把运行好的原图贴来上~~ 一.创建 ...

  4. MVC3+EF4.1学习系列(九)-----EF4.1其他的一些技巧的使用

    上节通过一系列重构 简单的项目就实现了 不过还有些EF的功能没有讲 这节就通过项目 讲讲EF其他的功能与技巧 一.直接执行SQL语句 通常来讲 EF 不用写SQL语句的  但是 在有些场合  比如对生 ...

  5. MVC3+EF4.1学习系列(四)----- ORM关系的处理

    上篇文章 终于把基础的一些操作写完了 但是这些都是单表的处理 而EF做为一个ORM框架  就必须点说说对于关系的处理 处理好关系 才能灵活的运用EF 关于关系的处理 一般就是  一对一   一对多  ...

  6. MVC3+EF4.1学习系列(八)-----利用Repository and Unit of Work重构项目

    项目最基础的东西已经结束了,但是现在我们的项目还不健全  不利于测试 重复性代码多   层与层之间耦合性高  不利于扩展等问题.今天的这章 主要就是解决这些问题的.再解决这些问题时,自己也产生了很多疑 ...

  7. MVC3+EF4.1学习系列(十一)----EF4.1常见的问题解决

    博客写了10篇了~有很多朋友私信问了一些问题,而且很多问题 大家问的都一样 这里说说这些常见问题的解决办法.如果大家有更好的解决办法~也希望分享出来 问题大概为这几个 一.ef4.1 codeFirs ...

  8. MVC3+EF4.1学习系列(十)----MVC+EF处理树形结构

    通过前几篇文章 我们处理了 一对一, 一对多,多对多关系 很好的发挥了ORM框架的做用 但是 少说了一种 树形结构的处理, 而这种树形关系 我们也经常遇到,常见的N级类别的处理, 以及经常有数据与类别 ...

  9. MVC3+EF4.1学习系列(七)-----EF并发的处理

    看这篇文章之前 推荐园子里的 这个文章已经有介绍了 而且写的很好~~ 可以先看下他的 再看我的 并发 1.悲观并发 简单的说 就是一个用户访问一条数据时 则把这个数据变为只读属性  把该数据变为独占 ...

随机推荐

  1. 微信js-sdk调用

    之前在做微信的时候,在微信支付还有调起微信扫一扫的时候,用过js-sdk.最近,被几个做前端的同学问到了具体的流程,想想,还是写下来好点.     微信js-sdk,是微信提供给网页开发设计者使用的, ...

  2. UIAlerView、UIActionSheet 和UIAlertViewController(点击注销确认按钮实现)

    - (IBAction)loginOut:(UIBarButtonItem *)sender { UIActionSheet *actionSheet = [[UIActionSheet alloc] ...

  3. Oracle客户端的安装

    首先Orcale的安装应该是很简单的,安装不好只是部熟悉,在其中遇见的一些问题记录下来,如果以后忘记了还可以看看. 首先最大的问题是安装客户端的时候要安装32位的,不管你的操作系统是32位还是64位的 ...

  4. 关于Python2字符编码的体会

    对于Python的字符编码问题也懵了很久,最近做爬虫多次遇到网页转码的问题,干脆彻底解决掉!Just Do it! 1.两种类型str与unicode str和unicode都是basestring的 ...

  5. 2016 Vultr VPS最新优惠码,赠送新用户70美元,亲测有效

    vultr肯定疯了,从来没有哪家海外vps像vultr那么大力度的优惠.近期,vultr vps再度推出优惠码,任何新用户注册即送20美元!要知道,vultr vps最便宜的vps套餐只要5美元/月, ...

  6. <密码的实现>输入密码的时候,显示“*”,而不是显示输入内容

    一开始还以为用C语言和C++不能实现输入密码的时候显示出“*”而不显示输入的内容呢!没想到偶然的机会试出了用while循环结构可以实现.以下是我整理的C语言和C++的代码,供初学者参考. 这是C语言实 ...

  7. ios发布笔录

    需要一张1024x1024的icon 发布尺寸4.7英寸  1334x7505.5英寸 2208-12424英寸  1136-6403.5英寸 960-640ipad  2048x1536 视频 ip ...

  8. git和SVN的区别

    1)Git是分布式的,SVN不是: 这 是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别.好处是跟其他同事不会有太多的冲突,自己写的代码放在自己电脑上,一段时间后再提交.合并, ...

  9. sqlite增删改查

    <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=&q ...

  10. Javascript中valueOf与toString区别

    前言 基本上,所有JS数据类型都拥有这两个方法,null除外.它们俩解决JavaScript值运算与显示的问题,重写会加大它们调用的优化. 测试分析 先看一例:var aaa = {  i: 10,  ...