上午的时候把复杂类型学习了一下,想着趁着周六日把Code First学习完,所以下午还是把Code First中的关系学习下。在数据库中最重要的恐怕就是E-R图了,E-R体现了表与表直接的关系。使用Code First也需要把这种表与表直接的关系映射到数据库中,所以关系映射在Code First中也是很重要的一节。Code First中主要包括一对一、一对多、多对多。

一、外键列名默认约定

Entity Framework Code First在根据默认约定创建外键时,外键列的名称存在3种方式:目标类型的键名,目标类型名称+目标类型键名称,引用属性名称+目标类型键名称。为了验证这3种方式创建了两个类:Province省份类、City城市类。

1.目标类型的键名

这种方式为要求在City表中外键列名与Province表中的主键列名相同,所以也就要求在City类中有定义与Province类中作为主键的属性。如在Province类中主键属性为ProvinceId,则需要在City类中也定义一个ProvinceId的属性。

    public class Province
{
[Key]
public string ProvinceId { get; set; } public string ProvinceName { get; set; } public virtual ICollection<City> Citys { get; set; }
}
    public class City
{
public int CityId { get; set; } public string CityName { get; set; } public string ProvinceId { get; set; } }

还有一点就是看有的博客有的加virtual关键字,有的不加,这两个的区别是什么呢?其实添加virtual关键字主要是为了懒加载,比如在获取Province时,不加virtual则会把Citys也会获取到,而加了virtual时只有在用到的时候才获取。如果在City类的ProvinceId上加[Required]约定,则Province与City就会是级联删除的关系。

2.目标类型名称+目标类型键名称

这种的话就是在City表中映射成Province(类型名称)+ProvinceId(类型键名称)。这种只需在上面的基础上稍作修改就是。即把City类中的ProvinceId属性去掉。

    public class City
{
public int CityId { get; set; } public string CityName { get; set; } }

3.引用属性名称+目标类型键名称

这种方式为要求在City表中外键列名为在City类中引用Province的属性名称 + Province类的主键名称。如:在City类中定义一个Province属性Pro,则生成的外键名称为Pro_ProvinceId。

    public class City
{
public int CityId { get; set; } public string CityName { get; set; } [Required]
public Province Pro { get; set; } }

上面也是加了[Required],也是构成了级联删除。

二、指定外键名

可以使用 [ForeignKey]约定来自定义外键名。

    public class City
{
public int CityId { get; set; } public string CityName { get; set; } public string ProId { get; set; } [ForeignKey("ProId")]//ProId一对要存在
public Province Province { get; set; } }

三、一对多关系

上面的Province和City就属于一对多的关系。

四、一对一

对于一对一的关系,首先它们要互相引用这是必须的。这还不够,还是会报错,需要设置谁参照谁,哪个是依赖类。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace EFCodeFirstModels
{
public enum SexType { Male, Female } [Table("Person")]
public class Person
{
[Key]
public string PersonId { get; set; }
//姓名 public string Name { get; set; }
//性别
public SexType Sex { get; set; }
//年龄
public int Age { get; set; } public virtual IDCard Card { get; set; } }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace EFCodeFirstModels
{ public class IDCard
{
[Key,ForeignKey("Person")]
public string PersonId { get; set; }
//法定出生日期
public DateTime BirthDate { get; set; } public virtual Person Person { get; set; } }
}

五、多对多

多对多关系用的最多的也举例子最多的恐怕就是用户和角色的关系了。一个用户可以有多个角色,一个角色包含多个用户。

    public class User
{
public int UserId { get; set; } public string Name { get; set; } public virtual List<Role> Roles { get; set; } }
    public class Role
{
public int RoleId { get; set; } public string Name { get; set; } public virtual List<User> Users { get; set; }
}

通过导航属性,Code First会默认生成一个中间表,来表示两个的多对多关系。

Entity Framework Code First根据默认约定生成的多对多关联关系的表时,默认启用多对多的数据级联删除,可以添加代码进行禁用。

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// 禁用多对多关系表的级联删除
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
}

六、对同一个实体多个引用的情况

首先看下下面的数据模型。

    public class Person
{
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; } public List<Lodging> PrimaryContactFor { get; set; }
public List<Lodging> SecondaryContactFor { get; set; }
}
    public class Lodging
{
public int LodgingId { get; set; }
public string Name { get; set; }
public string Owner { get; set; }
public bool IsResort { get; set; }
public decimal MilesFromNearestAirport { get; set; } //第一联系人
public virtual Person PrimaryContact { get; set; }
//第二联系人
public virtual Person SecondaryContact { get; set; } }

Lodging(旅店)有两个对Person表的引用,分别是PrimaryContact与SecondaryContact,同时,在Person表中也有对这两个联系人的导航:PrimaryContactFor与SecondaryContactFor。下面截图是它的映射。

可以看到,Lodings表中一下子有4个外键,这也太多了,因为有两套类型一样的导航属性与引用属性,Code First无法确定它们之间的对应关系,就单独为每个属性都创建了一个关系。这肯定不是我们所期望的,为了让Code First知道它们之间的对应关系,在这里要用到逆导航属性来解决。使用InverseProperty约定。

    public class Lodging
{
public int LodgingId { get; set; }
public string Name { get; set; }
public string Owner { get; set; }
public bool IsResort { get; set; }
public decimal MilesFromNearestAirport { get; set; } //第一联系人
[InverseProperty("PrimaryContactFor")]
public virtual Person PrimaryContact { get; set; }
//第二联系人
[InverseProperty("SecondaryContactFor")]
public virtual Person SecondaryContact { get; set; } }

EF实体框架之CodeFirst六的更多相关文章

  1. EF实体框架之CodeFirst四

    在EF实体框架之CodeFirst二中也提到数据库里面一般包括表.列.约束.主外键.级联操作.实体关系(E-R图).存储过程.视图.锁.事务.数据库结构更新等.前面几篇博客把表.存储过程.视图这些算是 ...

  2. EF实体框架之CodeFirst一

    对于SQL Server.MySql.Oracle等这些传统的数据库,基本都是关系型数据库,都是体现实体与实体之间的联系,在以前开发时,可能先根据需求设计数据库,然后在写Model和业务逻辑,对于Mo ...

  3. EF实体框架之CodeFirst五

    上一博客学习了下基本的约定配置,留下几个遗漏的,这篇就是学习下遗漏一复杂类型. 一.什么是复杂类型? 书中说道:“复杂类型也可视作值类型(?)可以作为附加属性添加到其他类.复杂类型与实体类型的区别在于 ...

  4. EF实体框架之CodeFirst二

    在codefirst一中也说了Mapping是实体与数据库的纽带,model通过Mapping映射到数据库,我们可以从数据库的角度来分析?首先是映射到数据库,这个是必须的.数据库里面一般包括表.列.约 ...

  5. EF实体框架之CodeFirst七

    前面的6篇博客基本把Code First学习的差不多了,今天这篇学习下code first中的并发控制和事务,基本也快学完了,顶多就差数据迁移. 在数据库中也是有锁和事务的概念,在C#中也是存在,当然 ...

  6. EF实体框架之CodeFirst三

    前两篇博客学习了数据库映射和表映射,今天学习下数据库初始化.种子数据.EF执行sql以及执行存储过程这几个知识. 一.数据库初始化策略 数据库初始化有4种策略 策略一:数据库不存在时重新创建数据库 D ...

  7. EF实体框架之CodeFirst八

    前面七篇基本把Code First学习了一下,不过code first中会出现一个问题,就是数据迁移的问题. 一.数据准备 还是在前面的demo上修改,这次使用Province和City类. publ ...

  8. C#.Net EF实体框架入门视频教程

    当前位置: 主页 > 编程开发 > C_VC视频教程 > C#.Net EF实体框架入门视频教程 > kingstone金士顿手机内存卡16G仅65元 1.EF实体框架之增加查 ...

  9. EF实体框架处理实体之间关联关系与EF延迟机制(下)

    在数据库中,表与表之间可能存在多种联系,比如,一对多,多对多的关系.当我们使用逻辑外键在数据库建立两张表之间的关系的时候,我们使用EF实体框架 必然也会将这种关系映射到我们的实体关系中来.所以,在我们 ...

随机推荐

  1. 从SqlServer现有数据生成Insert脚本

    步骤1,打开"Generate and Publish Objects"向导.右键点击要导出数据的数据库,选择Taks->GenerateScript 步骤2,选择要导出数据 ...

  2. windows 下安装nginx

    1.首先去官网下载 nginxWindows版本,官网下载:http://nginx.org/en/download.html 选择最新版本,下载到软件包后,解压文件包到指定目录,例如我的目录是D:\ ...

  3. XSLT

    一.简介 XSLT 是一种用于将 XML 文档转换为 XHTML 文档或其他 XML 文档的语言. XSL(eXtensible Stylesheet Language) -- 可扩展标记语言,主要用 ...

  4. Office文件上传自动生成缩略图

    来源:微信公众号CodeL 前不久产品经理提出一个X的需求,说上传office文件的时候需要将首页自动截图,用于显示文件列表的时候将文件第一页缩略图展示给用户.实现的方式有多种,这里给大家介绍一个简单 ...

  5. matlab生成HEX文件-任意信号 大于64K长度

    HEX文件格式不赘述,写里直接放上代码.请批评改正. %%convert a signal data into hex file format % data format:16bit % signal ...

  6. TestNG之执行测试类方式

    TestNG提供了很多执行方式,下面做简单介绍. 1.XML指明测试类,按照类名执行,其中可以指定包名,也可指定无包名: 带包名,运行ParameterSample类和ParameterTest类 & ...

  7. UESTC 919 SOUND OF DESTINY --二分图最大匹配+匈牙利算法

    二分图最大匹配的匈牙利算法模板题. 由题目易知,需求二分图的最大匹配数,采取匈牙利算法,并采用邻接表来存储边,用邻接矩阵会超时,因为邻接表复杂度O(nm),而邻接矩阵最坏情况下复杂度可达O(n^3). ...

  8. UVALive 6470 Chomp --记忆化搜索

    题意:给一个只有三行的方块阵(横向最多100个),然后p,q,r分别代表第1,2,3层的方格数,两人轮流去掉一个格子,此时这个格子的右上方都会被去掉,面临只剩最左下角的一个格子的状态的人输,问先手能否 ...

  9. HashTable Dictionary HashMap

    HashTable和HashMap 脑海中一直存在两个Hash,一个是HashMap另一个是HashTable,今天来总结一下两者的区别 相同点:表示根据键的哈希代码进行组织的键/值对的集合. 区别: ...

  10. [cb] Unity Editor 添加右键菜单

    需求 为Unity的Editor窗口添加右键菜单 实现代码 // This example shows how to create a context menu inside a custom Edi ...