实体类配置总结

Entity Framework 6 Code First 实践系列(1):实体类配置总结

2014-03-25 12:58 by TJerry, 719 阅读, 6 评论, 收藏编辑

EF实体类的配置可以使用数据注释或Fluent API两种方式配置,Fluent API配置的关键在于搞清实体类的依赖关系,按此方法配置,快速高效合理。为了方便理解,我们使用简化的实体A和B以及A、B的配置类AMap和BMap,来演示如何正确配置实体类关系的过程。

  1.  实体类配置

一、确定依赖关系:

假设实体B依赖于实体A(B->A),那么实体B中存在对实体A的引用。

二、实体类配置应该写在哪里?

假设B依赖于A(B->A),很显然,我们希望的是B表中生成外键(A表的主键值)。以下两种方式都可以实现相同的表结构,但毫无疑问我们应该在B的配置文件BMap中进行关系配置。

(1)B依赖于A,A可以对B的存在一无所知。

(2)A可以单独存在,配置写在哪里都不会对A表产生影响。

(3)B对A的依赖是通过在B表中生成外键(A表的主键)。

推荐的写法:

  1. public class BMap : EntityTypeConfiguration<B> { public BMap() { this.HasRequired(=> o.A).WithMany(o=>o.ListB); } }

摒弃的写法:

  1. public class AMap : EntityTypeConfiguration<A> { public AMap() { this.HasMany(=> o.ListB).HasRequired(=> o.A); } }

依赖的方向决定了使用的配置,这在实体类数量和关系复杂时尤其重要,假设有10个实体类依赖A,混合书写配置显然不可取,而在被依赖实体中配置的结果会导致经常修改A的配置文件,你甚至不肯定修改了类A的配置文件是会引起A表的变化。

三、配置依赖关系

配置文件的基类EntityTypeConfiguration包含了一系列Has方法用来配置实体类,其中HasOptional和HasRequired根据实体的引用属性配置实体关系。假设B依赖于A(B->A),HasOptional允许B单独存在,这将在B表中生成可空的外键。HasRequired不允许B单独存在,这将在B表中生成非空的外键。

  1.  HasRequired
  1.  HasOptional

四、配置关联类型

HasOptional和HasRequired分别返回OptionalNavigationPropertyConfiguration和RequiredNavigationPropertyConfiguration对象,我们使用其中的WithMany和WithOptional来配置关联的类型。

如果A:B = 1:N,我们使用WithMany。

  1.  1:N(外键可空)
  1.  1:N(外键不可空)

如果A:B= 1:1,我们使用WithOptional。1:1的关联要求外键的非空和唯一,数据库是通过表B的外键作为主键来实现。

  1.  1:1

四、可选导航属性

导航属性由关联类型决定,但其存在与否不会影响实体的依赖关系和关联类型。

对于B->A,如果A:B = 1:N,我们可以在A中添加ICollection<B>类型的导航属性,同时修改关系配置,将该属性传递给WithMany方法。

  1.  导航属性

如果A:B = 1:1,我们可以在A中添加B类型的导航属性,同时修改关系配置,将该属性传递给WithOptional方法。

五、显式外键属性

对于B->A,如果A:B = 1:1,外键就是主键。

如果A:B = 1:N,我们可以自定义导航属性对应的外键属性,首先在B中添加显式的用于外键的属性。

  1.  显式外键

WithMany返回DependentNavigationPropertyConfiguration对象,我们使用该对象的HasForeignKey方法,如果实体联系配置为HasOptional,则需要使用可空类型匹配。

  1.  外键配置

六、级联删除配置

HasForeignKey返回CascadableNavigationPropertyConfiguration对象,EF默认开启级联删除,当实体关系复杂导致无法开启级联删除时,我们使用该对象的WillCascadeOnDelete方法配置取消级联删除。

七、关于双向依赖

EF中实体的关联通过表的外键实现,1:N还是1:1都是通过外键实现。我们可以根据1:N配置的方式配置出双向依赖的表,但通常所谓的多对多都不是双向依赖。例如用户和角色、学生和课程、文章和标签等,甚至根本没有依赖,因为二者都可以独立存在,有的只是映射关系对二者的依赖,而这是1:N的问题。

我们使用EntityTypeConfiguration配置实体依赖,该类的ToTable、HasKey等实例方法都用于配置当前实体类映射的Table。HasRequired和HasOptional方法也会在对应的Table中生存外键,而HasMany方法则是其中的异类,偏偏配置的非当前实体类。

HasMany、WithMany除了在配置双向引用时替我们自动生成关系表,带来更多的是配置混乱。而所谓的自动生成关系表更是打破了我们实体类和Table的一一对应。在Microsoft.AspNet.Identity.EntityFramework 1.0中,我们可以看到IdentityUser和IdentityRole并没有通过双向引用自动生成关系表,而是定义了IdentityUserRole实体类用来映射:通过IdentityDbContext<TUser>的OnModelCreating配置我们可以看到虽然使用了HasMany配置TUser的Roles属性,但是完全可以在IdentityUserRole中配置。即使在2.0版本中依旧如此。

、常见的配置举例:

1.用户和角色:

(1)确定依赖关系:User和Role都可以单独存在,但UserRole不可以单独存在,因此存在的依赖是UserRole->User,UserRole->Role。

(2)配置依赖关系:UserRole不能单独存在,因此使用HasRequired。

(3)确定关联类型:User:UserRole==1:*;Role:UserRole=1:*,因此使用WithMany。

(4)显式的外键属性:在UserRole中添加UserId和RoleId作为显式的外键属性。

(5)可选的导航属性:在User和Role中添加ICollection<UserRole>类型的导航属性。

UserRole不应该存在重复的用户角色映射,因此使用外键作为联合主键。

  1.  UserRole

2.节点树:

(1)确定依赖关系:Category自依赖,Category->Category

(2)配置依赖关系:Category可以单独存在,因此使用HasOptional。

(3)确定关联类型:Category:Category==1:*,因此使用WithMany。

(4)显式的外键属性:在UserRole中添加ParentId,由于Category可以单独存在,ParentId为可空类型。

(5)可选的导航属性:在Category中添加ICollection<Category>类型的导航属性。

  1.  Category->Category
作者:Tjerry 

EF实体类配置总结的更多相关文章

  1. EntityFramework 系列:实体类配置-根据依赖配置关系和关联

    EF实体类的配置可以使用数据注释或Fluent API两种方式配置,Fluent API配置的关键在于搞清实体类的依赖关系,按此方法配置,快速高效合理.为了方便理解,我们使用简化的实体A和B以及A.B ...

  2. Entity Framework 6 Code First 实践系列(1):实体类配置-根据依赖配置关系和关联

    EF实体类的配置可以使用数据注释或Fluent API两种方式配置,Fluent API配置的关键在于搞清实体类的依赖关系,按此方法配置,快速高效合理.为了方便理解,我们使用简化的实体A和B以及A.B ...

  3. 【转】Entity Framework 6 Code First 实践系列(1):实体类配置-根据依赖配置关系和关联

    本文转自:http://www.cnblogs.com/easygame/p/3622893.html EF实体类的配置可以使用数据注释或Fluent API两种方式配置,Fluent API配置的关 ...

  4. hibernate 非xml实体类配置方法!

    hibernate 非xml实体类配置方法! 这个是hibernate.cfg.xml配置文件 <?xml version='1.0' encoding='UTF-8'?> <!DO ...

  5. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_2-7.接口配置文件自动映射到属性和实体类配置

    笔记 7.接口配置文件自动映射到属性和实体类配置     简介:使用@value注解配置文件自动映射到属性和实体类 1.添加 @Component或者Configuration 注解:        ...

  6. 从PowerDesigner表字段的Name到EF实体类属性的Display Name(根据PowerDesigner生成EF实体类中文注释和验证元数据)

    第一步:将PowerDesigner表字段的中文Name填入Comment中:工具-Execute Commands-Edit/Run Script... '********************* ...

  7. sonar排除实体类配置

    sonar覆盖率检查可以将一些实体类排除,maven项目可以在pom.xml文件中添加如下配置 <properties> <sonar.exclusions> src/main ...

  8. 关于EF实体类的一点思考

    在EF中修改一条记录时,一般是先查出该条记录,然后再通过TryUpdateModel或其他方式更新对应的属性.但我很讨厌这种要更新一条记录时,还要先去把记录查询出来的做法.我喜欢像sql语句那样的直接 ...

  9. JAVA Spring 简单的配置和操作 ( 创建实体类, 配置XML文件, 调试 )

    < 1 > 实体类 Person package java_spring.modle; /** * 一个实体类( Person ) */ public class Person { pri ...

随机推荐

  1. C和指针 (pointers on C)——第三章——数据

    第三章 数据 本章是非常重要的,在特定范围内使用.链接属性.存储类型.const.extern和statickeyword使用.几乎所有的公司是C++在采访的第一个问题. 总结: 具有external ...

  2. BMP图片转换为JPEG图片

    原文:BMP图片转换为JPEG图片 昨天在家学习,发现很多人把BMP图片转换为其它图片格式,有些人写得简单,有些人写得复杂. Insus.NET在想,一直在做文件上传,下载,或是图片剪切,都有进行过文 ...

  3. SqlServer发送邮件,定时作业

    今天偶然研究了一下sqlserver发送邮件的功能,之前听说过可以发,但是一直没尝试过,只是用C#写后台程序的方式来发邮件. 现在又多了一种发送邮件的途径. 大致的步骤如下: 1.配置sqlserve ...

  4. java数据结构系列——排列(2):有序阵列

    package Array; /** * 对数组排序.当添加到阵列保持有序数组元素: * @author wl * */ public class MyOrderArray { private lon ...

  5. SSIS从理论到实战,再到应用

    原文:SSIS从理论到实战,再到应用 一,是什么(What?) 1.SSIS是Microsoft SQL Server Integration Services的简称,是生成高性能数据集成解决方案(包 ...

  6. find your present (2) 2095

    Problem Description In the new year party, everybody will get a "special present".Now it's ...

  7. 经典算法题每日演练——第十七题 Dijkstra算法

    原文:经典算法题每日演练--第十七题 Dijkstra算法 或许在生活中,经常会碰到针对某一个问题,在众多的限制条件下,如何去寻找一个最优解?可能大家想到了很多诸如“线性规划”,“动态规划” 这些经典 ...

  8. C#关于图片的相关处理

    public class ImageHelper { /// <summary> /// 图片转换成字节流 /// </summary> /// <param name= ...

  9. 【足迹C++primer】49、超载,变化,运营商

    超载,变化,运营商 Conversion Operators 转换操作符 operator type() const Conversions to an array or a function typ ...

  10. C语言第11课

    主要内容:函数指针 一.函数指针定义 int  maxValue(int  a,int  b) { return   a > b ? a : b; } 函数名和数组名一样是地址,存在在代码区 i ...