|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
对于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[Extent1].[AID]AS[AID],[Extent1].[Title]AS[Title],[Extent2].[AID]AS[AID1],[Extent2].[Body]AS[Body]FROM[dbo].[A]AS[Extent1]INNERJOIN[dbo].[B]AS[Extent2]ON[Extent1].[B_AID]=[Extent2].[AID]WHERE1=[Extent1].[AID]
复制代码
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加一个[Required]属性,在实体考证时就请求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却不习惯了。 |
|