|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
C#中有两处地方用到new关键字,第一处也是最常见的一处是用在调用构造函数的时候,这种情况也是大家见的最多的一种。另一处是用在派生类中,作用有隐藏成员,切断继承关系等,相信第二处的用法大家明显要比第一处生疏。原觉得躲进代码天下,就能够不必弄干系,哪知“干系无处不在”。写代码多年以后,终究分明“面向对象的关头是弄好对象之间的干系”。而EntityFramework作为ORM中的嫡之星,首当其冲的任务就是共同对象弄好干系。
博客园开辟团队在利用EntitFramework的过程当中,被困扰最多的就是实体类之间的干系处置和这类干系与数据库之间的映照。以是,但愿经由过程这个系列文章将我们的狐疑、了解与理论履历拿出来与人人分享。常识与履历只要拿出来分享与传布,才会变得更有代价;躲在那,只会渐渐蜕变,终极随风而往。
干系分三种:一对1、一对多、多对多。我们就从“一对一”入手下手吧。“一对一”说复杂也复杂,说庞大也庞大;在实际天下,关头在因而否找对了谁人“一”,“找一团体,过一生”;而在代码天下,又该怎样“一对一”,让我们一同探究吧。
“一对一”也分两种情形:一种是单相思(单向),一种是两情相悦(双向)。单相思简单,两情相悦难啊;但一见就可以两情相悦究竟可遇而不成求,多半时分两情相悦来自于一方的单相思。
那我们就从最复杂的单相思入手下手吧——“我的眼中只要你,你的眼中会不会有我”。
场景形貌:园子里的每个“博客”(BlogSite)都对应着一个对手艺充斥热情的“人”(BlogUser)。我想观光一下园子,看看一切这些博客,看看这些博客面前的仆人(GetAllBlogSites)。
类图以下:
<br>
数据库表布局以下:
<br>
VS2010中的项目文件布局(基于博客园最新架构):
<br>
入手下手我们的路程:
1.第一步固然是测试,TDD可不是用来夸耀的专业名词,它是一个轮子,可让你在开辟的路途上走得更快,以是叫测试驱动。测试代码以下:- [TestMethod]publicvoidGetAllBlogSites_Test(){_aggBlogSiteService.GetAllBlogSites().ToList().ForEach(b=>{Console.WriteLine("BlogApp:"+b.BlogApp+",Author:"+b.BlogUser.Author);});}
复制代码 测试代码很复杂,就是挪用使用层的服务接口IAggBlogSiteService.GetAllBlogSites();
经由过程测试代码我们能够明白需求:猎取一个包括一切BlogSite的列表,每一个BlogSite包括BlogUser信息。这也是一个很罕见的查询需求。
2.看一下使用层的服务虚现:- 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设置的详细代码以下:- 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如许举行界说的:- //针对“一对一”干系的设置modelBuilder.Entity<BlogSite>().HasRequired(b=>b.BlogUser).WithRequiredDependent().Map(conf=>conf.MapKey("UserID"));
复制代码 注:如许界说时,必要正文失落BlogSite的UserID属性。
这类体例,可以失掉准确的了局,但天生的SQL很奇异:- 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]
复制代码 无需多说,看一眼你就没法忍耐如许的SQL。
再看看利用WithMany()天生的SQL:- 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")],代码以下:- 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的话,微软把很多工具都封装好了,学起来可能容易一点。 |
|