多级包含示例
场景
在领域驱动设计(DDD)中,多级包含是指一个领域实体包含其他领域实体的概念。下面是一个使用“班级”、“学生”和“教师”描述多级包含的例子:
解决方案
实体模型
/// <summary>
///班级
/// </summary>
public class Class
{
/// <summary>
///班级ID
/// </summary>
private int _classId;
/// <summary>
///编号
/// </summary>
private byte _number;
/// <summary>
///学生
/// </summary>
private List<Student> _students;
/// <summary>
///班级ID
/// </summary>
public int ClassId
{
get => _classId;
set => _classId = value;
}
/// <summary>
///编号
/// </summary>
public byte Number
{
get => _number;
set => _number = value;
}
/// <summary>
///学生
/// </summary>
public List<Student> Students
{
get => _students;
set => _students = value;
}
}
/// <summary>
///学生
/// </summary>
public class Student
{
/// <summary>
///班级ID
/// </summary>
private int _classId;
/// <summary>
///学生姓名
/// </summary>
private string _name;
/// <summary>
///学生ID
/// </summary>
private string _studentId;
/// <summary>
///学生ID
/// </summary>
public string StudentId
{
get => _studentId;
set => _studentId = value;
}
/// <summary>
///学生姓名
/// </summary>
public string Name
{
get => _name;
set => _name = value;
}
/// <summary>
///班级ID
/// </summary>
public int ClassId
{
get => _classId;
set => _classId = value;
}
}
/// <summary>
///教师
/// </summary>
public class Teacher
{
/// <summary>
///教授班级
/// </summary>
private List<Class> _classes;
/// <summary>
///姓名
/// </summary>
private string _name;
/// <summary>
///教师ID
/// </summary>
private int _teacherId;
/// <summary>
///教师ID
/// </summary>
public int TeacherId
{
get => _teacherId;
set => _teacherId = value;
}
/// <summary>
///姓名
/// </summary>
public string Name
{
get => _name;
set => _name = value;
}
/// <summary>
///教授班级
/// </summary>
public List<Class> Classes
{
get => _classes;
set => _classes = value;
}
}
模型配置
/// <summary>
///多级包含配置
/// </summary>
public class MultiIncludeConfiguration : MySqlContextConfigProvider
{
/// <summary>由派生类实现,获取数据库连接字符串。</summary>
protected override string ConnectionString => Configuration.MySqlConnectionString;
/// <summary>获取一个值,该值指示是否启用存储结构映射</summary>
protected override bool EnableStructMapping => true;
/// <summary>使用指定的建模器创建对象数据模型。</summary>
/// <param name="modelBuilder"></param>
protected override void CreateModel(ModelBuilder modelBuilder)
{
//配置班级实体型
var classEntity = modelBuilder.Entity<Class>();
//配置主键
classEntity.HasKeyAttribute(p => p.ClassId).HasKeyIsSelfIncreased(true);
//配置教师实体型
var teacherEntity = modelBuilder.Entity<Teacher>();
//配置主键
teacherEntity.HasKeyAttribute(p => p.TeacherId).HasKeyIsSelfIncreased(true);
//配置学生实体型
var studentEntity = modelBuilder.Entity<Student>();
//配置主键
studentEntity.HasKeyAttribute(p => p.StudentId).HasKeyIsSelfIncreased(false);
//隐式关联也可以独立映射 需要配置ToTable
//配置教师与班级间的关联型
var classTeacherAssociation = modelBuilder.Association<Class, Teacher>();
//配置关联端 End1为Class 在关联表中Class的主键ClassId映射为ClassId
classTeacherAssociation.AssociationEnd(p => p.End1).HasMapping("ClassId", "ClassId");
//配置关联端 End2为Teacher 在关联表中Teacher的主键TeacherId映射为TeacherId
classTeacherAssociation.AssociationEnd(p => p.End2).HasMapping("TeacherId", "TeacherId");
//多对多 独立映射表
classTeacherAssociation.ToTable("Teaching");
//配置教师实体型中的关联引用 左端就是关联型上自己类型的这一端 即End2 右端即为另外一端End1
teacherEntity.AssociationReference(p => p.Classes).HasLeftEnd("End2").HasRightEnd("End1");
//配置班级和学生的关联型
var classAssStudent = modelBuilder.Association<Class, Student>();
//配置关联端 End1为Class 在关 联表中Class的主键ClassId映射为ClassId
classAssStudent.AssociationEnd(p => p.End1).HasMapping("ClassId", "ClassId");
//配置关联端 End2为Student 在关联表中Teacher的主键StudentId映射为StudentId
classAssStudent.AssociationEnd(p => p.End2).HasMapping("StudentId", "StudentId");
//一对多 伴随表即可
classAssStudent.ToTable("Student");
//配置班级实体型中的关联引用 左端就是关联型上自己类型的这一端 即End1 右端即为另外一端End2
classEntity.AssociationReference(p => p.Students).HasLeftEnd("End1").HasRightEnd("End2");
}
}