三代档案可以自己拿吗了4个4又拿了 4个2能引爆...

太原警察打死讨薪农民工引爆全国舆论,民工死后4天才拿上2万元工钱(转载)_天涯海角社区
太原警察打死讨薪农民工引爆全国舆论,民工死后4天才拿上2万元工钱(转载)
作者:退休处级干部 发布日期: 15:13:00
作者:退休处级干部 回复时间: 15:30:00
作者:夏风如歌 回复时间: 15:52:28
作者:15年猛料 回复时间: 21:43:48
作者:摆个地摊发财 回复时间: 21:55:01
作者:167888c 回复时间: 22:00:10
作者:糖宝嘻嘻 回复时间: 16:00:49
作者:看太累了 回复时间: 16:27:55
作者:xniu999 回复时间: 22:26:05
作者:xniu999 回复时间: 22:35:30
作者:平等思想 回复时间: 23:33:05
作者:小王晨 回复时间: 23:43:42
作者:马陵道边人 回复时间: 23:49:38
作者:u_ 回复时间: 00:00:06
作者:鞭打侉子 回复时间: 00:07:36
作者:马陵道边人 回复时间: 00:43:56
作者:xniu999 回复时间: 14:02:47
作者:xniu999 回复时间: 14:03:53
作者:xniu999 回复时间: 14:07:33
作者:温柔不带刀 回复时间: 09:31:25
作者:带响的弓箭2014 回复时间: 22:44:40
作者:Hi_Dan 回复时间: 22:48:09
作者:u_ 回复时间: 22:58:20
作者:镗床哥 回复时间: 23:14:26
作者:俺是纸老虎 回复时间: 00:58:54
作者:风轻花又落 回复时间: 01:14:22
作者:都御史 回复时间: 01:50:40下次自动登录
现在的位置:
& 综合 & 正文
operamasks-ui2.0 +MVC4.0+EF5.0实战 当EntityFramework遇上Json,引爆 循环引用 这颗雷
   正文之前先说两句,距离上篇博客已将近两个月,这方面的学习和探索并没有停止,而是前进道路上遇上了各种各样的问题,需要不断的整理、反思和优化,这段时间的成果,将在最近陆续整理发出来。
个人感觉国内心态太浮躁了,很少有能深入研究下去并将自己经验分享的人,可能很忙,也可能嫌麻烦。特别是面向新技术,尤其是在学习资料有限的情况下,愿意花费时间摸索和分享的人实在太少太少,遇到问题,搜索结果一抓一大把,但是往往都是转载,连最起码的自己验证都没有,结果就是以讹传讹,不仅对解决问题无用,反而容易产生误导。最近这段时间感触颇深,遇到问题往往需要去认真考虑选择合适英文关键词从英文网站里找解决方案。
这块技术,我也是新手,遇到的问题比较多,我发现以现在的水平和能力写成一个逻辑性比较强的系列很有难度,因此决定从点入手,将发现问题-》寻找解决方法-》最终解决方法整个过程记录下来,最后再将一个个点串起来,形成线。作为自己的总结和反思,也为后来者提供一些经验和帮助,能少走一些弯路。同时,也留下一些目前无法解决的问题,欢迎交流,欢迎指正。
好了,转入正文,采用operamasks-ui2.0 +MVC4.0+EF5.0这种模式或者说架构,首先面对的是一个不可避免的问题,前后台交换数据,目前最流行、最高效的方式就是Json(上去几年可能用xml的多一些,关于Json和xml的优缺点,不在此处描述,有兴趣的自己查资料吧)。也就是数据通过EF取出来,这时候是对象,通过MVC调度,经过序列化转换成Json格式,传给前台,前台开发框架(operamasks-ui或easyui或extJS甚至Jquery等等)接收后进行解析和展现。这个时候问题就来了,如何序列化?如果没做过这块开发,会觉得这很简单,包括我在之前的系列里也提到过,自己为object写了一个扩展方法:
public static string ToJsonString(this Object obj)
JavaScriptSerializer s = new JavaScriptSerializer();
StringBuilder sb = new StringBuilder();
s.Serialize(obj, sb);
return sb.ToString();
  然后在控制器里做以下处理
public ActionResult GetMenu()
IQueryable&Menu& menu = MenuService.Query();
var nodes = new List&TreeNode&();
foreach (var item in menu.ToList())
TreeNode node = new TreeNode();
node.id = item.ID;
node.pid = item.ParentID;
node.text = item.N
node.url = item.U
node.expanded = "true";
nodes.Add(node);
return Content(nodes.ToJsonString());
事实上,上面的方式是多此一举,完全没必要。更简便的做法是,直接调用Json(object)方法就行了,也即把上面的return Content(nodes.ToJsonString());替换为return Json(nodes);。其实,我在写扩展方法实现序列化之前,用过这种方式,结果发现前台接收不到数据,才自己又去查找资料,使用JavaScriptSerializer类序列化对象,采用return Content(序列化后的Json)方式。至于当初为什么不好用,原因也找到了,一个小细节,也是新手常犯的一个错误,在这也说一下。问题不是出在序列化对象为Json格式上,而是http协议的方法上。对,你没看错,就是http协议,前台通过ajax调用后台方法的时候,一定注意是Get还是Post,如果是Get,那么默认情况下,控制器里的方法处理完毕后,调用Json(object)是禁止Get获取的,而是必须调用其重载函数return Json(object, JsonRequestBehavior.AllowGet);这个问题很隐蔽,不知道这么回事,就会莫名其妙,明明后台调试传回了数据,但前台死活就接收不到数据。还有一个隐含的地雷就是,你在使用一些前台框架的一些控件的时候,往往只调用其方法,而其内部往往也是通过ajax来加载和刷新数据的,一不留意,也会发生上述问题,导致前台取不到数据。
上面篇幅不小,其实只说了一个小问题,为下文做一下铺垫。
下面就来说核心问题。采用EntityFramework,采用Code First模式,先定义实体类,类有普通属性和导航属性。以部门为例,这是一种常见的自关联模式,即定义一个字段,指向其上级部门,从而形成无限级层次扩展,很明显,这是一种一对多关系,即一个部门只有一个上级部门,而可能有多个下级部门。如下所示(已做简化处理,未包括一些无关属性)。
class Department
[DisplayName("内码")]
public string ID { get; set; }
[DisplayName("部门名称")]
public string Name { get; set; }
public string ParentID { get; set; }
[DisplayName("上级部门")]
[ForeignKey("ParentID")]
public virtual Department ParentDept { get; set; }
public virtual ICollection&Department& SonDepts { get; set; }
  通过使用ForeignKey属性标记,可以实现自主指定映射成数据库的字段名称。如果不使用,EF也能自动生成,不过要按约定的规则(类名+ID)来写属性名,我还是喜欢自己的地盘自己做主,自动生成容易出现指示不明、修改出错的问题。至于ForeignKey里面的参数怎么写,刚学习的时候也困惑了半天,这个ForeignKey应该标记在属性ParentID上呢还是标记在导航属性ParentDept上呢?里面的参数是不是要写对应外键的库表名称呢?试了试,好像有些写法就提示出错,有些就提示正常,提示正常的还不止一种写法。后来通过摸索和查资料,才知道两种方法都可以,其一就是我上面写的,标记在导航属性ParentDept上,参数为属性ParentID,另一种就是标记在属性ParentID,里面参数是导航属性ParentDept,即
   [ForeignKey("ParentDept")]
public string ParentID { }
public virtual Department ParentDept { }
   现在回过头来觉得这样相互定义很自然,但当初的时候确实为究竟该怎么写才对困扰了一阵。
   继续说正文。对于一对多关系,EF处理模式,就是加一个导航属性,指明上级,再加一个导航属性,指明下级,就像上面写的
   public virtual Department ParentDept { }
public virtual ICollection&Department& SonDepts { }
   当初我也是这样做的,完全是照网上一些教程做的。可以说,这样做本身其实也没什么问题,但序列化成Json对象的时候,就出了大问题,你会得到一个错误提示:序列化类型为XX的对象时检测到循环引用。刚看到这个错误的时候可能会觉得莫名其妙,为什么会报这个错误呢?其实原理很简单,序列化的时候,先找个一个部门A,然后有下级部门的导航属性,序列化下级部门B的时候,其上级部门的导航属性指向了部门A,结果就是循环引用,跟死循环一个道理。
如何解决这个问题呢?有一种解决方式,就是使用linq to entity,把基本属性取出来,抛弃掉导航属性,但这种方式局限性比较大,需要将实体类的非导航属性字段人工写一遍,很繁琐,通用性差,并且抛弃了引用属性,延迟加载的优点也丢了。
   那么有没有更优的解决方式呢?
  我从网上查资料,有人说将db.ContextOptions.ProxyCreationEnabled=false; 也有人说 将db.ContextOptions.LazyLoadingEnabled=false,还有人说为导航属性加上[ScriptIgnore]标记,我实际试过,没用,我觉得不是MVC版本问题,而是这根本就不是问题的本质,传这些资料的人根本就没自己验证过是否真有用。事实上,只要导航属性有Virtual关键字,那么EF就会延迟加载,序列化的时候就会发生循环引用,这才是问题的本质。既然找到了问题本质,那解决是不是也很简单了,把virtual关键字去掉就行了。这样做确实可行,序列化的时候不会报循环引用错误,但是,这样做的时候,EF延迟加载的优点也彻底被抛弃了。比如说,如果有延迟加载,你完全可以在视图里直接用model=&model.ParentDept.Name来绑定显示部门名称,不用写任何。如果没有延迟加载,那么,model.ParentDept对象就是null,你需要在控制器的方法里通过DbSet &Department&.Find(ParentID)方法找到并实例化一个Department对象,然后将名称通过ViewBag这个动态对象传递给前台,你可以想象一下,这有多繁琐。
如何既能排除掉循环引用的雷,又能保留延迟加载的优点呢?查阅了大量资料,然后试验各种所谓的解决方案,最终,在一家国外网站上找到了解决方法,就是定义序列化Json的行为,使其忽略引用对象(导航属性),在MVC Web应用的App_Start目录的WebApiConfig.cs文件的Register方法末尾追加一句,只需要一句:
  config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling= Newtonsoft.Json.PreserveReferencesHandling.O
  其实原文还有一句config.Formatters.Remove(config.Formatters.XmlFormatter);
这句跟问题无关,不要加。当然老外同样有以讹传讹的人士存在,说加config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling= Newtonsoft.Json.ReferenceLoopHandling.I以及config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling
= Newtonsoft.Json.ReferenceLoopHandling.S这两种方法看上去有效,经过实际验证无效。
  加了这句还不算完,你还需要在实体类中,一对多关系情况下,只保留其中一个导航属性,上面部门的例子里,你保留ParentDept可以,保留SonDepts也行,只保留一个,EF能正确识别出来这是一对多,库表中生成正确的外键。如果你仍然两个导航属性都留着,那么恭喜你,你还是会得到循环引用的错误提示。
采用上面的方式,你就可以为导航属性加上virtual关键字了,也可以保留ef延迟加载的优点了。
到这还没完,还有个尾巴。关系里还有一种常见的,就是多对多,比如角色和人员,一个角色有多个人员,一个人员有多个角色,按照教程,应该在人员实体类里加一个导航属性public virtual ICollection&Role& Roles { }, 在角色实体类里加一个导航属性public virtual ICollection&User& Users { },ef会自动识别,然后生成一张只有UserID和RoleID两个字段的中间库表。这一切看上去都没问题,就是常规的处理方式。但是,你在序列化成Json的时候,又会遭遇循环引用这颗雷,即使是按我上面那样那样去设置,仍然避免不了,想一想,依旧是死循环。
后来我想出了一个办法,就是自己定义一个中间实体,名字是RoleUser,然后,在User实体类里加public virtual ICollection&RoleUser& RoleUsers { },在Role实体类中加public virtual ICollection&RoleUser& RoleUsers { },也就是,一个多对多关系转成了两个一对多,采用上面的方式就能处理了。这样还有一个优点,就是可以在中间关系映射表中增加其他字段,比如创建时间、创建人,以及一些必要的业务信息,比如在学生的选课记录上增加成绩字段。
以上就是我自己摸索出来的解决方式,就目前来说,是自己能想到的最优解决方式,供大家参考下,欢迎批评指正,提供更佳的实现方式。
  可能是EF用的人还不多,但是Hibernate应该同样有类似问题吧,没接触过Hibernate,也欢迎了解Hibernate人说下在这方面是如何处理的。
<span style="color: #年4月5日补充修正:
  本文发表后,有两位朋友留言提出自己的办法,一是用JsonIgnore属性,二是用DataContractJsonSerializer类,看上去貌似有用,经过试验,发现还是无效,不过也进一步提供了思路。其实文章整理出来后,就发现问题其实很简单了,就是序列化对象的时候如何处理循环引用的问题,只要为序列化类指定行为,那么一切问题也就解决了。其实我一直有点不踏实,就是我原来琢磨出来的方法,在WebApiConfig.cs里加对Json类的控制,是否真的能起作用?之前不了解WebApi,又查了下资料,发现跟普通的Control调用是两回事,也就意味着,不论在里面做什么,不应该对现有的Controller里面的方法产生影响。方向搞错了……进而想一下,如果去掉那段修改的代码,那么我的程序应该也能运行,于是试了一下,果然正常……只要将一对多关系只保留一个导航属性,那么自然就不存在循环引用的问题,我以为正确的解决方法,是在反复试验和多处修改后产生的混乱错觉,由此差点也成为误导别人的凶手……  前面的摸索并不都是无用功,对这块了解已经深入了,也有了新的想法。方向明确了,就是为序列化类指定行为来控制序列化时的行为。那么如何来控制呢,前面用JavaScriptSerializer类为object类写过扩展方法,明显没有可控的属性,而之前的摸索也知道了Newtonsoft.Json.JsonConvert这个类可以控制循环应用的行为处理,尝试改了一下之前的扩展方法,果然可以。
  之前一直怀疑Controller.Json方法默认内部调用的是JavaScriptSerializer类来序列化对象的,按这个思路搜了一下,果然发现有人深入研究过,网址见,是通过查看MVC源码获取的,并且提供了如何继承默认Controller和重载Json方法,把序列化的JavaScriptSerializer替换成Newtonsoft.Json.JsonConvert的方法,看上去逻辑上没问题,具体没验证。考虑到这种方式比较麻烦,且以后升级MVC版本容易出问题,还是用我以前写的扩展方法来解决最为方便。
为Oject对象增加ToJsonString方法(注意对项目添加Newtonsoft.Json.dll引用)
using System.T
using System.Web.Script.S
using Newtonsoft.J
namespace Common.Extentions
public static class ObjectExtentions
public static string ToJsonString(this Object obj)
JsonSerializerSettings jsSettings = new JsonSerializerSettings();
jsSettings.ReferenceLoopHandling = ReferenceLoopHandling.I
return JsonConvert.SerializeObject(obj, jsSettings);
然后在Control里,获取到数据对象后,return Content(data.ToJsonString());
这样处理后,你可以在一对多关系中,同时使用两个导航属性,并且都添加virtual关键字,从而保留延迟加载特性。
  由此想到多对多关系也可以常规化处理了,不过你想为中间表增加字段,还得用上文拆分的思路,欢迎验证,欢迎指正。
&&&&推荐文章:
【上篇】【下篇】站内网址搜索
本页最后更新: 0:39:05
【《澳门娱乐城》今日数据趣谈:5场得分30+ 哈登平詹皇并列No.1】
网站分类:
网站名称:
网站地址:
站长邮箱:
站长QQ:
收录时间:
报告错误:
《澳门娱乐城》今日数据趣谈:5场得分30+ 哈登平詹皇并列No.1已报错(0)次,打不开请
收录查询:
数据统计:
今日点入:0 总点入:0 总点出:8
网站简介:
[澳门娱乐城-澳门娱乐城网址-澳门娱乐城开户-澳门娱乐城代理-/Html/AoMenYuLeCheng0378/]新浪体育讯 北京时间11月25日,NBA今天共进行了7场常规赛,以下是这几场比赛中出现的一些有趣数据。  今天火箭以91-86战胜尼克斯,詹姆斯-哈登全场三分球12投7中,砍下赛季单场新高36分。此前的纪录是35分,是在2战76人的比赛中拿下的。命中7记三分追平哈登生涯单场纪录,此前他曾有3场命中7记三分球,全是加盟火箭之后。  此外,本赛季迄今,哈登已有5场比赛单场得分30+,追平了詹姆斯,并列联盟第一。而凭借本场的36分,哈登生涯总得分也突破7000分大关(7022分)。  上赛季2战尼克斯,哈登分别拿下36分和37分,今天又得到36分。由此,他也成为继1997-98赛季的迈克尔-乔丹后,首位连续3场对尼克斯均得分35+的球员。  此外,本场获胜后,火箭11胜3负,这是队史自1996-97赛季后,单赛季前14场比赛的最佳开局。该赛季火箭开局13胜1负。  在今天快船战胜黄蜂的比赛中,布雷克-格里芬和克里斯-保罗分别拿下22分,此外格里芬还有16个篮板,保罗还送出15次助攻。近4个赛季,一支球队有2名球员分别打出得分20+篮板15+和得分20+助攻15+的比赛,此前仅有1场,那是今年1月3日湖人战胜爵士,保罗-加索尔得到23分17个篮板,肯德尔-马绍尔得到20分15次助攻。  在今天之前,从2012年4月开始,开拓者共有13场比赛(不包含加时赛)让对手有3人得分20+,全部败北。但本场,尽管76人阵中,迈卡威(24分)、亨利-西姆斯(22分)和托尼-罗滕(20分)均得分20+,开拓者还是以114-104获胜,送给对手开季14连败。  本场拉马库斯-阿尔德里奇拿下全队最高的33分11个篮板。近5个赛季,开拓者有球员单场打出得分30+篮板10+的常规赛共有27场,全是阿尔德里奇一人打出来的。(魑魅)  在今天骑士以106-74大胜魔术的比赛中,骑士首节就以26-16领先,其中勒布朗-詹姆斯一人独得16分。这是詹姆斯生涯第11场首节得分追平或超过对方全队首节得分的比赛。而这11场,他所在球队共赢了10场。  今天猛龙以104-100战胜太阳,约纳斯-瓦兰休纳斯拿下全场最高的27分11个篮板。生涯迄今瓦兰休纳斯共出战了156场常规赛,但他单场拿下全场最高的得分和篮板(不包含并列)的比赛,本场仅是第二场。此前一场是今年3月14日战胜灰熊的比赛,他得到23分9个篮板,均为全场最高。  此外,单场27分也刷新了瓦兰休纳斯生涯单场得分纪录。今年4月9日在对阵76人的比赛中,他曾拿下26分。  今天步行者以111-100战胜小牛,唐纳德-斯隆拿下29分。近2个赛季,在所有未经过选秀进入NBA的球员中,仅有一人单场(不包含加时赛)得分超过本场的斯隆,他就是篮网的米尔扎-泰勒托维奇。今年1月24日篮网的一场比赛,对手也是小牛,他拿下34分。(本赛季初,在一场加时负于奇才的比赛中,斯隆曾单场拿下31分。)(魑魅)[澳门娱乐城-澳门娱乐城网址-澳门娱乐城开户-澳门娱乐城代理-/Html/AoMenYuLeCheng0378/]
【最新来访网站】
?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&
【相关点出网站】
?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&?&
免责声明:888导航以上所有广告内容均为赞助商广告提供,对其经营行为本网站恕不负责。Copyright&
All Right Reserved
强烈建议使用 IE5.0 以上浏览器 分辨率三只猴子分一筐桃子.第一只猴子将全部桃子平均分成7分,自己拿走2分多2个,第二只猴子将余下的桃子平均分成3份,自己拿走2份少4个.第三只猴子拿到最后20个.这筐桃子共有多少个?_百度作业帮
三只猴子分一筐桃子.第一只猴子将全部桃子平均分成7分,自己拿走2分多2个,第二只猴子将余下的桃子平均分成3份,自己拿走2份少4个.第三只猴子拿到最后20个.这筐桃子共有多少个?
用倒推法 :第三只猴子拿 的桃子如果减去4就应该 是剩 的三分之一,也就是说 (20-4)*3=48个是第一只猴子拿走后剩 的.这些桃子再加上2只就应该 是剩下的5/7.这筐桃子一共有(48+2)/(5/7)=70只
第二只猴子拿之前有(20-4)÷(1-2÷3)=48(个)这筐桃子共有(48+2)÷(1-2÷7)=70(个)
设桃子共有X个,则第一个猴子拿走的桃子为
,第二个猴子拿走的桃子为
[X-(2/7X+2)]乘以2/3-4,在+上第三个猴子拿的20个,共=X,所以解方程式得X=70
您可能关注的推广瑞士积雪研究所的科学家日前利用炸药在瑞士西昂附近的Vallee de la Sionne河谷引发大规模雪崩,希望借此来研究和预测雪崩事件。与此同时,勇敢的摄影师抓拍到许多雪崩的壮观场景。
照片显示,大...【】(4/6)
登录驱动之家
没有帐号?
用合作网站帐户直接登录

我要回帖

更多关于 档案可以自己拿吗 的文章

 

随机推荐