本文学习旺杰兄的 CodeFirst 系列教程而写。尽量摆脱之前的影子写出自己的理解

表间关系、级联删除

简单玩法已经走通了,但是我就是想搞点事出来。今天来搞搞表间关系和级联删除

表间关系

毫无疑问在设计表的时候,对于两张有关联的表,我们要做一对一或一对多的外键关系。这样在使用EF的时候可以轻松的使用导航属性不说,也使得表结构更加简单明朗。使用CodeFirst我们该如何配置呢?

一对一

我们这边有这样两个实体。User、UserCard。 一个用户肯定只会拥有一个身份证号、而一个身份证号肯定也只能属于一个人。这就是一个典型的一对一关系。

[Table("T_User")]
public class User
{
public User()
{
UserId = new Guid(Guid.NewGuid().ToString("D")); ;
} [Key]
public Guid UserId { get; set; } [Required]
[MaxLength(20)]
public string Name { get; set; } [Timestamp]
public byte[] RowVersion { get; set; } public List<UserRole.UserRole> UserRoles { get; set; } /// <summary>
/// 扩展
/// </summary>
public UserAddress UserAddress { get; set; } /// <summary>
/// 一个用户拥有一个身份证
/// </summary>
public UserCard UserCard { get; set; } }
/// <summary>
/// 用户证件实体
/// </summary>
[Table("T_User_Card")]
public class UserCard
{
public UserCard()
{
UserId = new Guid(Guid.NewGuid().ToString("D"));
}
[Key]
public Guid UserId { get; set; } [MaxLength(18)]
public string IdCard { get; set; } //一个证件只能属于一个人..一对一
public User User { get; set; } }

之前也提到,配置映射有两种方式。写说注解的方式,很简单。使用ForeignKey()的方式可以轻松的搞定

[Key,ForeignKey("User")]
public Guid UserId { get; set; }

但是在实际开发中大多会用Fluent Api 这个配置也很容易

HasRequired(u => u.User).WithOptional(u => u.UserCard);

对关系的配置做一下梳理

Has方法:

  • HasOptional: 前者包含后者一个实例  (可为null)
  • HasRequired:前者包含后者一个不为null的实例
  • HasMany:前者包含后者实例的集合

With方法

  • withOptional:后者包含前者一个实例 (可为null)
  • withRequired:后者包含前者一个不为null的实例
  • withMany:后者包含前者实例的集合

我们的Fluent Api的配置可以清楚的看出来是 UserCard包含一个User不为null的实例而User包含一个UserCard可为null的实例

这里记录本人不是很推荐的写法

public class UserCardMap : EntityTypeConfiguration<UserCard>
{
public UserCardMap()
{
//不推荐的写法
HasRequired(u => u.User).WithMany().HasForeignKey(u => u.UserId);
}
}

首先我们搞了一个UserId做为外建,使用了Fluent Api做配置映射,下面指定了UserId为外建。看看我们数据库中的关系图是佬样的吧。下图可以看到建立了两个关系 一个UserCard中的Id为主键而User表中生成了一个UserDard_Id为外键。下面则是使用了User表中的主键 User_Card表中的UserId做为外建 。 这样看起来是双向的一对一的关系。好吧,我不需要这样的配置。复杂,而且WithMany看起来像是一对多一样

一对多

之前的User和UserRole就是一对多关系,当时并没有做什么。EF为我们自动做了配置,且在UserRole表中添加了User_UserId做外键。这样虽然爽,但是!我就是想让外键叫UserId。这要怎么做呢?当然简单了。。

这是在UserRole中进行配置,代表UserRole拥有一个不为null的User实例,User拥有UserRole的集合。MayKey指定外键名为UserId

HasRequired(o => o.User).WithMany(u => u.UserRoles).Map(o => o.MapKey("UserId"));

Updata-database一下就可以看到表的变化了,UserId做为了外键

多对多

多对多关系,开发中经常会用到。我们的User与UserRole之前是一对多的关系。但是如果我们再去细想。一个角色 (老师、公民、程序员) 可以属于多个人。而一个人也可以同时拥有这些角色。这就是一个明显的多对多(-.-之前欠考虑了)。那么要改造成多对多的关系。首先把UserRole表中的User改成list集合

我们在数据库建表的时候遇到多对多关系,一般都会建立一个中间表用来存放两张表的记录。在CodeFirst中我们也要进行这样的配置。

//多对多的配置
HasMany(o => o.Users).WithMany(o => o.UserRoles).Map(m =>
{
m.ToTable("T_User_UserRole_Config");
m.MapLeftKey("UserId");
//这里为了区分,把id改成了UserRoleId
m.MapRightKey("UserRoleId");
});

Update-database一下看一下数据库就大功告成了!

级联删除

表一旦有了关系,那么自然会生出很多事,我们的主从表一旦主表中的数据删除从表的Fluent Api配置如不是optional都会默认级联删除。嗯,因缺斯挺。但是某些业务需求并不允许我们这么做。数据是很宝贵的东西,也是为什么软删除这么流行的原因。即使主表被删除了但是某些从表中的数据很有价值,这时我们就不得不考虑了。正确的做法全局关闭级联删除。在OnModelCreting中添加

//全局关闭级联删除
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

那么问题又来了,有些从表中的数据真的只要主表中记录被删除就变的毫无价值,存在就是浪费空间的货。这种还是需要级联删除的,我们可以在xxMap中单独为它开启级联删除

//开启级联删除
HasRequired(u => u.User).WithOptional(u => u.UserCard).WillCascadeOnDelete(true);

EF-CodeFirst-3搞事的更多相关文章

  1. EF CodeFirst 如何通过配置自动创建数据库<当模型改变时>

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精    本篇为进阶篇,也是弥补自己之前没搞明白的地方,惭愧 ...

  2. 新年奉献MVC+EF(CodeFirst)+Easyui医药MIS系统

    本人闲来无事就把以前用Asp.net做过的一个医药管理信息系统用mvc,ef ,easyui重新做了一下,业务逻辑简化了许多,旨在加深对mvc,ef(codefirst),easyui,AutoMap ...

  3. 新年奉献MVC+EF(CODEFIRST)+EASYUI医药MIS系统(转)

    出处:http://www.cnblogs.com/chenlinzhi/p/4332628.html 本人闲来无事就把以前用Asp.net做过的一个医药管理信息系统用mvc,ef ,easyui重新 ...

  4. 1.【使用EF Code-First方式和Fluent API来探讨EF中的关系】

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/relationship-in-entity-framework-using-code-firs ...

  5. [.NET领域驱动设计实战系列]专题一:前期准备之EF CodeFirst

    一.前言 从去年已经接触领域驱动设计(Domain-Driven Design)了,当时就想自己搭建一个DDD框架,所以当时看了很多DDD方面的书,例如领域驱动模式与实战,领域驱动设计:软件核心复杂性 ...

  6. [转]Using Entity Framework (EF) Code-First Migrations in nopCommerce for Fast Customizations

    本文转自:https://www.pronopcommerce.com/using-entity-framework-ef-code-first-migrations-in-nopcommerce-f ...

  7. EF CodeFirst增删改查之‘CRUD’

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精    本篇旨在学习EF增删改查四大操作 上一节讲述了EF ...

  8. EF CodeFirst 创建数据库

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精    话说EF支持三种模式:Code First   M ...

  9. EF Codefirst 初步学习(二)—— 程序管理命令 更新数据库

    前提:搭建成功codefirst相关代码,参见EF Codefirst  初步学习(一)--设置codefirst开发模式 具体需要注意点如下: 1.确保实体类库程序生成成功 2.确保实体表类库不缺少 ...

  10. Android搞事篇——使用Intent跳转界面

    跳转页面基本分为三个步骤: 1.初始化一个intent:(一个intent就够用了): 2.传入intent参数: 3.调用startactivity();实现跳转页面 具体操作如下 首先你需要一个项 ...

随机推荐

  1. 细细品味Storm_Storm简介及安装

    Storm是由专业数据分析公司BackType开发的一个分布式实时数据处理软件,可以简单.高效.可靠地处理大量的数据流.Twitter在2011年7月收购该公司,并于2011年9月底正式将Storm项 ...

  2. UWP 拉勾客户端

    前些天, 用 Xamarin.Forms (XF) 将就着写了个拉勾的 UWP 和 Android 的客户端. XF 对 Android  和 IOS 的支持做的很到位, 但是对 UWP 的支持目前仅 ...

  3. viso图插入Word中大片空白解决办法

    按住CTRL-->将鼠标指向绘图页边缘-->指针变为移动符号(双向箭头)-->按下左键修改绘图页大小.

  4. vim 快捷键

    1.vim ~/.vimrc 进入配置文件 如果不知道vimrc文件在哪,可使用 :scriptnames 来查看 set nu #行号 set tabstop=4 #一个tab为4个空格长度 set ...

  5. SharePoint Web Part Error – The Specified Solution Was Not Found

    If you develop, release and add a SharePoint 2010 sandboxed solution web part to a page, then change ...

  6. 0929mysql前缀索引如何找到合适的位数

    前缀索引,是指对于VARCHAR/TEXT/BLOB类型的字段建立索引时一般都会选择前N个字符作为索引.索引很长的字符列,会让索引变得大且慢.索引开始的部分字符,这样可以大大节约索引空间,从而提高索引 ...

  7. Nginx之负载均衡服务器揭秘

    Nginx代理服务器, 一次性代理多台后端机器, 利用负载算法, 决定将当前请求传递给某台服务器执行. 有哪些后台服务器?例如微软的IIS,Apache,Nginx 负载算法是什么? 加权轮询. ng ...

  8. elasticsearch和hadoop集成,gateway.type hdfs设置

    配置elasticsearch的存储路径为hdfs需要两步,安装插件 elasticsearch-hadoop,在联网的情况下在命令窗口运行:plugin -install elasticsearch ...

  9. ElasticSearch的各种服务的URL

    1.curl192.168.106.58:9200/_cat/health?v 集群健康查看 epoch      timestamp cluster       status node.total ...

  10. 全面理解Context

    出处:http://blog.csdn.net/lmj623565791/article/details/40481055,本文出自:[张鸿洋的博客] 本文大多数内容翻译自:http://www.do ...