ASP.NET网页编程之Entity Framework - 理清干系 - 基于共享主键的单向一对一干系仓酷云 ...
对于new隐藏成员的作用,往往是出于使用了一个第三方类库,而你又无法获得这个类库的源代码,当你继承这个类库的某个类时,你需要重新实现其中的一个方法,而又需要与父类中的函数使用同样的函数,这是就需要在自定义的子类中把那个同名函数(或成员)加上new标记,从而隐藏父类中同名的成员。在上篇文章中,我们理了一下基于外键联系关系的单向一对一干系。在这篇文章中,我们理一理“基于共享主键的单向一对一干系”,找出EntityFramework中准确的映照干系。1、明白需求,也就是EntityFramework准确映照以后要到达的效果
1)数据库布局要切合请求——共享主键。所下图所示,数据库中表A与表B的主键都是AID。
2)实体干系要切合请求——单向一对一干系。我们经由过程上面的UML类图来表达:
上图中只要A到B的联系关系箭头,这就是“单向”,这个箭头也暗示A依附B,在代码中的体现就是A有一个导航属性A.B。
上图中箭头两端的两个1就是“一对一”,存在一个A,一定存在一个对应的B;存在一个B,一定存在一个对应的A。
EDM中的实体干系要与UML类图中的干系分歧。
实体A的界说:
publicclassA{publicintAID{get;set;}publicstringTitle{get;set;}publicBB{get;set;}}
实体B的界说:
publicclassB{publicintAID{get;set;}publicstringBody{get;set;}}
3)耐久化操纵要切合请求
只同意A与B一同举行耐久化,测试代码以下:
vara=newA();a.Title="titletest";a.B=newB();a.B.Body="bodytest";using(EfUnitOfWorkef=newEfUnitOfWork()){ef.Set<A>().Add(a);ef.SaveChanges();}
不同意A与B各自独自的耐久化,测试代码以下:
//不同意的耐久化操纵vara=newA();a.Title="titlea";using(EfUnitOfWorkef=newEfUnitOfWork()){ef.Set<A>().Add(a);ef.SaveChanges();}varb=newB();b.Body="bodyb";using(EfUnitOfWorkef=newEfUnitOfWork()){ef.Set<B>().Add(b);ef.SaveChanges();}
4)天生的SQL查询语句要切合请求
好比如许的查询:
using(EfUnitOfWorkef=newEfUnitOfWork()){ef.Set<A>().Include(a=>a.B).Where(a=>a.AID==1).ToList();}
天生的SQL查询语句应当是:
SELECT.AS,.AS,.AS,.ASFROM.ASINNERJOIN.ASON.=.WHERE1=.
2、用最笨的办法找出谜底
这个最笨的办法是,对四种映照干系一一举行测试,看哪一个与我们想要的效果最分歧。
上面我们分离来看看在分歧的映照干系设置下EntityFramework的举动。
1).HasRequired(a=>a.B).WithMany();
FluentAPI:
protectedoverridevoidOnModelCreating(DbModelBuildermodelBuilder){modelBuilder.Entity<B>().HasKey(b=>b.AID);modelBuilder.Entity<A>().HasRequired(a=>a.B).WithMany();}
a)EF天生的数据库布局:
表A多了一个字段B_AID,并经由过程B_AID联系关系至表B的主键AID。数据库布局纷歧致,不切合请求。
b)EF天生的EDM图:
EDM与UML中的干系界说纷歧致,这里是一对多干系,我要的是一对一干系,不切合请求。
c)不同意实体A的独自耐久化,但同意实体B的独自耐久化,不切合请求。
d)天生的SQL查询语句切合请求。
【小结】数据库布局不切合请求,实体干系不切合请求,耐久化不切合请求,天生的SQL查询语句切合请求。
2).HasRequired(a=>a.B).WithOptional();
FluentAPI:
protectedoverridevoidOnModelCreating(DbModelBuildermodelBuilder){modelBuilder.Entity<B>().HasKey(b=>b.AID);modelBuilder.Entity<A>().HasRequired(a=>a.B).WithOptional();}
a)EF天生的数据库布局:
数据库布局切合请求。
b)EF天生的EDM图:
联系关系的一端是0..1,也就是同意“存在一个B,不存在一个A”的情形,实体干系不切合请求。
c)不同意实体A的独自耐久化,但同意实体B的独自耐久化,不切合请求。
d)天生的SQL查询语句切合请求。
【小结】数据库布局切合请求,实体干系不切合请求,耐久化不切合请求,SQL查询语句切合请求。
3).HasRequired(a=>a.B).WithRequiredDependent();
FluentAPI:
protectedoverridevoidOnModelCreating(DbModelBuildermodelBuilder){modelBuilder.Entity<B>().HasKey(b=>b.AID);modelBuilder.Entity<A>().HasRequired(a=>a.B).WithRequiredDependent();}
a)天生的数据库布局与.WithOptional();一样,切合请求。
b)EF天生的EDM图:
实体干系是“单向一对一”干系,与UML类图分歧。但类的摆放地位纷歧致,在EDM中,B在A的后面,也就是B是Principal,我们但愿A是Pricipal,有点纷歧致。
c)不同意实体A的独自耐久化,但同意实体B的独自耐久化,不切合请求。
d)天生的SQL查询语句切合请求。
【小结】数据库布局切合请求,实体干系有点不切合请求(Pricipal纷歧致),耐久化不切合请求,SQL查询语句切合请求。
4).HasRequired(a=>a.B).WithRequiredPrincipal();
FluentAPI:
protectedoverridevoidOnModelCreating(DbModelBuildermodelBuilder){modelBuilder.Entity<B>().HasKey(b=>b.AID);modelBuilder.Entity<A>().HasRequired(a=>a.B).WithRequiredPrincipal();}
a)天生的数据库布局与.WithOptional();一样,切合请求。
b)EF天生的EDM图:
实体干系是“单向一对一”干系,与UML类图分歧,A是Pricipal,切合请求。
c)同意实体A的独自耐久化,不同意实体B的独自耐久化,不切合请求。
d)天生的SQL查询语句:
publicclassB{publicintAID{get;set;}publicstringBody{get;set;}}0
我们想要的是INNERJOIN,这里倒是两个LEFTOUTERJOIN,不切合请求。
等等。。。我们改一下查询的LINQ语句尝尝,改成:
publicclassB{publicintAID{get;set;}publicstringBody{get;set;}}1
悔改以后,天生的SQL查询语句切合请求:
publicclassB{publicintAID{get;set;}publicstringBody{get;set;}}2
【小结】数据库布局切合请求,实体干系切合请求,耐久化不切合请求,SQL查询语句切合请求。
3、总结与剖析
数据库布局实体干系耐久化SQL查询语句WithMany()不切合不切合不切合切合WithOptional()切合不切合不切合切合WithRequiredDependent()切合不切合不切合切合WithRequiredPrincipal()切合切合不切合切合
从下面的表中能够出,成就最好的是WithRequiredPrincipal(),但它有一个中央不切合请求,就是同意实体A的独自耐久化。
为何实体B不克不及独自耐久化?看数据库的外键干系就晓得谜底(A_B外键束缚的功烈):
那我们只需办理“不同意实体A的独自耐久化”的成绩,就可以完成“基于共享主键的单向一对一干系”的完善映照。
既然数据库中欠好动手,那就从实体类动手吧。给实体A的导航属性A.B加一个属性,在实体考证时就请求A.B必需有一个对应的实体B的实例。修正后的实体A的代码以下:
publicclassB{publicintAID{get;set;}publicstringBody{get;set;}}3
经由勉力,我们终究找到了最好谜底——
关于“基于共享主键的单向一对一”干系,EntityFramework中准确的映照干系界说是:
modelBuilder.Entity<A>().HasRequired(a=>a.B).WithRequiredPrincipal();
竟发现没有太大的帮助。总觉得要用起来,感觉到不了位。因为公司机器的原因,一直没有安装vs.net(也从来没有用过)。以前做asp的时候一直用DW(感觉其代码联想功能不错),可现在到了asp.net却不习惯了。 当然我们在选择Asp.net主机是,除了要考虑服务提供商在版本是否是实时更新以外,机房的环境和配置也是非常重要的,通常选择骨干网的机房,在速度和稳定性上会非常有保证。 能产生和执行动态、交互式、高效率的站占服务器的应用程序。运用ASP可将VBscript、javascript等脚本语言嵌入到HTML中,便可快速完成网站的应用程序,无需编译,可在服务器端直接执行。容易编写。 Servlet却在响应第一个请求的时候被载入,一旦Servlet被载入,便处于已执行状态。对于以后其他用户的请求,它并不打开进程,而是打开一个线程(Thread),将结果发送给客户。由于线程与线程之间可以通过生成自己的父线程(ParentThread)来实现资源共享,这样就减轻了服务器的负担,所以,JavaServlet可以用来做大规模的应用服务。 大哥拜托,Java在95年就出来了,微软垄断个妹啊,服务器市场微软完全是后后来者,当年都是Unix的市场,现在被WindowsServer和Linux抢下大片,包括数据库也一样。 在一个项目中谁敢保证每天几千万甚至几亿条的数据不丢失?谁敢保证应用的高可靠性?有可以借签的项目吗? 有一丝可惜的是,这个系列太强了,Java阵营的朋友根本就是哑口无言...争论之火瞬间被浇灭,这不是我想这么早就看到的,但是值了。 现在的ASP.net分为两个版本:1.1和2.0Asp.net1.1用VS2003(visualstudio2003)编程。Asp.net2.0用VS2005(visualstudio2005)编程。现在一般开发用的是VS2003。 当然我们在选择Asp.net主机是,除了要考虑服务提供商在版本是否是实时更新以外,机房的环境和配置也是非常重要的,通常选择骨干网的机房,在速度和稳定性上会非常有保证。 通过这次激烈的讨论,我从大家身上学到了太多,开阔了眼界,不管是支持我的还是骂我的,都感谢你们。 可以看作是VC和Java的混合体吧,尽管MS自己讲C#内核中更多的象VC,但实际上我还是认为它和Java更象一些吧。首先它是面向对象的编程语言,而不是一种脚本,所以它具有面向对象编程语言的一切特性。 现在主流的网站开发语言无外乎asp、php、asp.net、jsp等。 ASP.Net和ASP的最大区别在于编程思维的转换,而不仅仅在于功能的增强。ASP使用VBS/JS这样的脚本语言混合html来编程,而那些脚本语言属于弱类型、面向结构的编程语言,而非面向对象。
页:
[1]