仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 988|回复: 11
打印 上一主题 下一主题

[学习教程] ASP.NET教程之Entity Framework 理论系列 ―― 弄好干系 - 单相思(单向一对一仓酷云 ...

[复制链接]
变相怪杰 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:21:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
C#中有两处地方用到new关键字,第一处也是最常见的一处是用在调用构造函数的时候,这种情况也是大家见的最多的一种。另一处是用在派生类中,作用有隐藏成员,切断继承关系等,相信第二处的用法大家明显要比第一处生疏。原觉得躲进代码天下,就能够不必弄干系,哪知“干系无处不在”。写代码多年以后,终究分明“面向对象的关头是弄好对象之间的干系”。而EntityFramework作为ORM中的嫡之星,首当其冲的任务就是共同对象弄好干系。
博客园开辟团队在利用EntitFramework的过程当中,被困扰最多的就是实体类之间的干系处置和这类干系与数据库之间的映照。以是,但愿经由过程这个系列文章将我们的狐疑、了解与理论履历拿出来与人人分享。常识与履历只要拿出来分享与传布,才会变得更有代价;躲在那,只会渐渐蜕变,终极随风而往。
干系分三种:一对1、一对多、多对多。我们就从“一对一”入手下手吧。“一对一”说复杂也复杂,说庞大也庞大;在实际天下,关头在因而否找对了谁人“一”,“找一团体,过一生”;而在代码天下,又该怎样“一对一”,让我们一同探究吧。
“一对一”也分两种情形:一种是单相思(单向),一种是两情相悦(双向)。单相思简单,两情相悦难啊;但一见就可以两情相悦究竟可遇而不成求,多半时分两情相悦来自于一方的单相思。
那我们就从最复杂的单相思入手下手吧——“我的眼中只要你,你的眼中会不会有我”。
场景形貌:园子里的每个“博客”(BlogSite)都对应着一个对手艺充斥热情的“人”(BlogUser)。我想观光一下园子,看看一切这些博客,看看这些博客面前的仆人(GetAllBlogSites)。
类图以下:

<br>
数据库表布局以下:

<br>
VS2010中的项目文件布局(基于博客园最新架构):

<br>
入手下手我们的路程:
1.第一步固然是测试,TDD可不是用来夸耀的专业名词,它是一个轮子,可让你在开辟的路途上走得更快,以是叫测试驱动。测试代码以下:
  1. [TestMethod]publicvoidGetAllBlogSites_Test(){_aggBlogSiteService.GetAllBlogSites().ToList().ForEach(b=>{Console.WriteLine("BlogApp:"+b.BlogApp+",Author:"+b.BlogUser.Author);});}
复制代码
测试代码很复杂,就是挪用使用层的服务接口IAggBlogSiteService.GetAllBlogSites();
经由过程测试代码我们能够明白需求:猎取一个包括一切BlogSite的列表,每一个BlogSite包括BlogUser信息。这也是一个很罕见的查询需求。
2.看一下使用层的服务虚现:
  1. publicIEnumerable<BlogSite>GetAllBlogSites(){return_blogSiteReposiotry.Entities.Include(b=>b.BlogUser).Where(b=>b.IsActive==true);}
复制代码
很复杂的LINQ查询,必要注重的中央是Include,只要用了Include,在实行时EntityFramework才会天生BlogSite与BlogUser两张表的INNERJOIN查询。不然,就会利用提早加载(LazyLoading),在每次会见BlogSite.BlogUser属性时举行查询;假如前往100个BlogSite,就会发生100次对BlogUser表的查询。
3.进进关头环节,怎样针对这类单向的一对一干系对EntityFramework举行设置(这里用的是CodeFirst)。
有两种体例能够完成:一种是经由过程FluentAPI,在OnModelCreating中完成;一种是经由过程DataAnnotations间接在实体类上设置。
a)FluentAPI设置的详细代码以下:
  1. protectedoverridevoidOnModelCreating(DbModelBuildermodelBuilder){modelBuilder.Entity<BlogUser>().ToTable("BlogUser");modelBuilder.Entity<BlogUser>().HasKey(u=>u.UserID);modelBuilder.Entity<BlogSite>().ToTable("BlogSite");modelBuilder.Entity<BlogSite>().HasKey(b=>b.BlogID);//针对“一对一”干系的设置modelBuilder.Entity<BlogSite>().HasRequired(b=>b.BlogUser).WithMany().HasForeignKey(b=>b.UserID);modelBuilder.Conventions.Remove<IncludeMetadataConvention>();base.OnModelCreating(modelBuilder);}
复制代码
只需看“一对一”干系设置部分的代码。HasRequired(b=>b.BlogUser)很好了解就是界说“一对一”的干系;WithMany()今朝是个迷,Many与One-to-One干系看起来驴头不合错误马嘴,但就得如许,这但是我们经由良多实验,最初试出来的办理办法。不然会天生让人啼笑皆非的SQL语句。上面我们来浏览一下EF天生的让人啼笑皆非的SQL。
入手下手我们是用FluentAPI如许举行界说的:
  1. //针对“一对一”干系的设置modelBuilder.Entity<BlogSite>().HasRequired(b=>b.BlogUser).WithRequiredDependent().Map(conf=>conf.MapKey("UserID"));
复制代码
注:如许界说时,必要正文失落BlogSite的UserID属性。
这类体例,可以失掉准确的了局,但天生的SQL很奇异:
  1. SELECT[Extent1].[BlogID]AS[BlogID],[Extent1].[BlogApp]AS[BlogApp],[Extent1].[IsActive]AS[IsActive],[Join1].[UserID1]AS[UserID],[Join1].[Author]AS[Author],[Join3].[BlogID]AS[BlogID1]FROM[dbo].[BlogSite]AS[Extent1]LEFTOUTERJOIN(SELECT[Extent2].[UserID]AS[UserID1],[Extent2].[Author]AS[Author]FROM[dbo].[BlogUser]AS[Extent2]LEFTOUTERJOIN[dbo].[BlogSite]AS[Extent3]ON[Extent2].[UserID]=[Extent3].[UserID])AS[Join1]ON[Extent1].[UserID]=[Join1].[UserID1]LEFTOUTERJOIN(SELECT[Extent4].[UserID]AS[UserID2],[Extent5].[BlogID]AS[BlogID]FROM[dbo].[BlogUser]AS[Extent4]LEFTOUTERJOIN[dbo].[BlogSite]AS[Extent5]ON[Extent4].[UserID]=[Extent5].[UserID])AS[Join3]ON[Extent1].[UserID]=[Join3].[UserID2]WHERE1=[Extent1].[IsActive]
复制代码
  1. GetAllBlogSites()f
复制代码
无需多说,看一眼你就没法忍耐如许的SQL。
再看看利用WithMany()天生的SQL:
  1. SELECT[Extent1].[BlogID]AS[BlogID],[Extent1].[BlogApp]AS[BlogApp],[Extent1].[IsActive]AS[IsActive],[Extent1].[UserID]AS[UserID],[Extent2].[UserID]AS[UserID1],[Extent2].[Author]AS[Author]FROM[dbo].[BlogSite]AS[Extent1]INNERJOIN[dbo].[BlogUser]AS[Extent2]ON[Extent1].[UserID]=[Extent2].[UserID]WHERE1=[Extent1].[IsActive]
复制代码
多洁净,这才是我们想要的。
b)另有一种复杂的办法,经由过程DataAnnotations在BlogSite的UserID属性上设置[ForeignKey("BlogUser")],代码以下:
  1. publicclassBlogSite{publicintBlogID{get;set;}publicstringBlogApp{get;set;}publicboolIsActive{get;set;}[ForeignKey("BlogUser")]publicGuidUserID{get;set;}publicBlogUserBlogUser{get;set;}}
复制代码
这是EntityFramework4.0入手下手引进的新特征,欲知概况,请看Foreignkeyvs.IndependentassociationsinEntityFramework4。
一个ForeignKey能够到达WithMany一样的效果,够复杂。
写到这,单向一对一干系弄好咧。接着干嘛呢?这还用问,运转测试,出工!

<br>
返来一下,完全代码还没分享:
CNBlogsDemo代码下载
J2EE比较成熟一点,一些比较出名的企业应用软件都是基于J2EE的。以后的发展就不好说了。不过net网页编程比较烦,学.net的话,微软把很多工具都封装好了,学起来可能容易一点。
沙发
发表于 2015-1-30 05:45:36 | 只看该作者
ASP.net1.1和2.0在程序上的语法也有很大不同,现在2.0属于新出来的,不知道半年后会不会有3.0(说笑一下)。Windows2003系统自动支持ASP和ASP.net环境,不用安装任何程序。Asp.net属于编译语言。ASP的最大不同(ASP属于解释语言)。
再见西城 该用户已被删除
板凳
发表于 2015-1-30 14:22:05 | 只看该作者
当然我们在选择Asp.net主机是,除了要考虑服务提供商在版本是否是实时更新以外,机房的环境和配置也是非常重要的,通常选择骨干网的机房,在速度和稳定性上会非常有保证。
简单生活 该用户已被删除
地板
发表于 2015-2-16 06:42:34 | 只看该作者
asp.net最主要特性包括:◆编程代码更简洁◆网站可实现的功能更强大◆运行效率高◆节省服务器的动作资源
蒙在股里 该用户已被删除
5#
发表于 2015-3-1 17:16:08 | 只看该作者
弱类型造成潜在的出错可能:尽管弱数据类型的编程语言使用起来回方便一些,但相对于它所造成的出错几率是远远得不偿失的。
灵魂腐蚀 该用户已被删除
6#
发表于 2015-3-2 22:04:27 | 只看该作者
asp.net最主要特性包括:◆编程代码更简洁◆网站可实现的功能更强大◆运行效率高◆节省服务器的动作资源
兰色精灵 该用户已被删除
7#
发表于 2015-3-3 14:48:08 | 只看该作者
但是java靠开源打出的一片天地,特别是在微软的垄断下能打开今天的局面还是有它的生命力的。
海妖 该用户已被删除
8#
发表于 2015-3-6 14:55:00 | 只看该作者
我的意思是.net好用,从功能上来说比JAVA强还是很明显的。
冷月葬花魂 该用户已被删除
9#
发表于 2015-3-6 15:40:48 | 只看该作者
在asp.net虚拟主机的服务提供商中,目前首推的是CNNIC的其中一家域名注册机构---时代互联(www.now.net.cn),他们早在2001年微软刚推出Asp.net时就推出了对应的Asp.net虚拟主机了,经笔者的使用测试,他提供的Asp.net性能非常的稳定,版本也会定期的更新,目前他的
莫相离 该用户已被删除
10#
发表于 2015-3-7 15:56:53 | 只看该作者
代码的可重用性差:由于是面向结构的编程方式,并且混合html,所以可能页面原型修改一点,整个程序都需要修改,更别提代码重用了。
谁可相欹 该用户已被删除
11#
发表于 2015-3-15 09:15:33 | 只看该作者
能产生和执行动态、交互式、高效率的站占服务器的应用程序。运用ASP可将VBscript、javascript等脚本语言嵌入到HTML中,便可快速完成网站的应用程序,无需编译,可在服务器端直接执行。容易编写。
小妖女 该用户已被删除
12#
发表于 2015-3-21 22:53:15 | 只看该作者
以上是语言本身的弱点,在功能方面ASP同样存在问题,第一是功能太弱,一些底层操作只能通过组件来完成,在这点上是远远比不上PHP/JSP,其次就是缺乏完善的纠错/调试功能,这点上ASP/PHP/JSP差不多。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 09:44

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表