Entity Framework 一对多关系映射
时间:2022-07-24
本文章向大家介绍Entity Framework 一对多关系映射,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
EF中关系映射也是一个很关键的内容,关系映射和属性映射一样,也是在 OnModelCreating 中配置映射。EF中的关系映射有如下三种:
- One-to-Many Relationship(一对多)
- Many-to-Many Relationship(多对多)
- One-to-One Relationship(一对一)
我们今天先讲解 One-to-Many Relationship(一对一关系)
零、创建所需类
- 所有实体类公用的抽象基类
public abstract class Base
{
public int Id { get; set; }
public DateTime CreateTime { get; set; }
public DateTime ModifiedTime { get; set; }
}
- 客户类和订单类
public class Customer : Base
{
public string Name { get; set; }
public string Email { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class Order : Base
{
public byte Quanatity { get; set; }
public int Price { get; set; }
public int CoustomerId { get; set; }
public virtual Customer Customer { get; set; }
}
一、One-to-Many Relationship
- 创建Map映射类
在编写代码之前,我们先分析一下客户和订单的关系。一个客户可以有多个订单,但一个订单只能属于一个客户,所以我们用到了EF中的 HasRequired,一个客户又存在多个订单,因此也使用到了 WithMany ,同时 Order 表中有 CustomerId 作为外键,因此我们用到了 HasForeignKey 。根据我们的分析,编写代码如下:
public class CustomerMap : EntityTypeConfiguration<Customer>
{
public CustomerMap()
{
//数据库映射的表名称
ToTable("Customer");
//主键
HasKey(p => p.Id);
//属性映射的字段属性
Property(p => p.Name).HasColumnType("VARCHAR").HasMaxLength(50).IsRequired();
Property(p => p.Email).HasColumnType("VARCHAR").HasMaxLength(50).IsRequired();
Property(p => p.CreateTime);
Property(p => p.ModifiedTime);
//设置关系
HasMany(t => t.Orders).WithRequired(t => t.Customer).HasForeignKey(t => t.CoustomerId).WillCascadeOnDelete(false);
}
}
public class OrderMap : EntityTypeConfiguration<Order>
{
public OrderMap()
{
ToTable("Order");
HasKey(p => p.Id);
Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(p => p.Quanatity);
Property(p => p.Price);
Property(p => p.CoustomerId);
Property(p => p.CreateTime);
Property(p => p.ModifiedTime);
}
}
- 注册映射类
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var typeToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => !String.IsNullOrEmpty(t.Namespace))
.Where(t => t.BaseType != null
&& t.BaseType.IsGenericType
&& t.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach(var type in typeToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
base.OnModelCreating(modelBuilder);
}
注1:在实际项目中需要编写很多的实体类,如果将所有实体类的映射直接写在 OnModelCreating 中会造成代码臃肿,不易维护,因此我们在这里将每个类的映射写在对应的映射文件中,最后再将每个类的映射类注册到 OnModelCreating 中
注2:上述代码和描述是从客户的方向连编写的关系映射,如果以订单的角度来编写关系映射的话,只需删掉CustomerMap中的关系配置,在OrderMap中增加关系配置部分修改如下:
HasRequired(p => p.Customer).WithMany(p => p.Orders).HasForeignKey(p => p.CoustomerId).WillCascadeOnDelete(false);
运行控制台代码后,我们将在数据库看到表和表关系都被创建了:
- 接口测试 | 22 requests基础入门
- 图的存储结构的实现(C/C++实现)
- 树和二叉树的存储结构的实现(C/C++实现)
- Selenium3源码之异常模块篇
- 移位密码原理及算法实现
- 排序算法的实现(C/C++实现)
- [开源] 分享导出博客园文章成本地 Markdown 文件存储的工具
- 单表代替密码原理及算法实现
- 【Android开发学习笔记之一】5大布局方式详解
- Selenium3源码之common下action_chains.py模块分析
- 图的简单应用(C/C++实现)
- 一个很easy的脚本--php获取服务器端的相关信息
- Kubernetes网络解决方案的比较
- OSX 上初步尝试 asp.net 5
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法