现实的数据关系中经常会出现一对多的关系,比如说一个班级可以有很多的学生,一个校区可能有很多的班级。 我们这边要看的就是EF core 是如何定义这个东西的。
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime BirthDate { get; set; }
//学生的班级Id
public int? ClassId { get; set; }
public int Grade { get; set; }
public decimal TotalScore { get; set; }
//一个学生有一个班级
public virtual Class Class { get; set; }
public override string ToString()
{
return $"Id:{Id},Name:{Name},TotalScore:{TotalScore}";
}
}
/// <summary>
/// 班级
/// </summary>
public class Class
{
public int Id { get; set; }
public string Name { get; set; }
//一个班级的校区Id
public int? SchoolAreaId { get; set; }
//一个班级有一个校区, 不弄成virtual也是可以的
public SchoolArea SchoolArea { get; set; }
//一个班级有多个学生
public virtual ICollection<Student> Students { get; set; }
}
/// <summary>
/// 校区
/// </summary>
public class SchoolArea
{
public int Id { get; set; }
public string Name { get; set; }
//一个校区有很多的班级
public virtual ICollection<Class> Classes { get; set; }
public static implicit operator SchoolArea(string value)
{
return new SchoolArea()
{
Name = value
};
}
}
public class MalemaDbContext : DbContext
{
public MalemaDbContext(DbContextOptions<MalemaDbContext> options)
: base(options)
{
this.Database.EnsureCreated();
}
//可以看到我们把上面的实体类都加了进来了
public DbSet<Student> Students { get; set; }
public DbSet<Class> Classes { get; set; }
public DbSet<SchoolArea> SchoolAreas { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>().Property(x => x.Name).HasMaxLength(50);
base.OnModelCreating(modelBuilder);
}
}
会在数据库当中生成三个表
可以用下面的方式来添加数据。
public void InitData()
{
using (var dbCotnext = this.dbContextFactory.CreateDbContext())
{
List<Student> students = GetStudents();
if (dbCotnext.Students.Count() < 1)
{
dbCotnext.SchoolAreas.AddRange(GetSchoolAreas());
dbCotnext.SaveChanges();
dbCotnext.Classes.AddRange(GetClasses());
dbCotnext.AddRange(students);
dbCotnext.SaveChanges();
}
}
}
private static List<SchoolArea> GetSchoolAreas()
{
return new List<SchoolArea> { "南区", "北区", "东区" };
}
private static List<Class> GetClasses()
{
var class1 = new Class() { Name = "104", SchoolAreaId = 1 };
var class2 = new Class() { Name = "105", SchoolAreaId = 1 };
var class3 = new Class() { Name = "106", SchoolAreaId = 2 };
return new List<Class> { class1, class2, class3 };
}
private static List<Student> GetStudents()
{
var student1 = new Student() { BirthDate = DateTime.UtcNow.AddYears(-12), ClassId = 1, Grade = 2, Name = "张三", TotalScore = 200 };
var student2 = new Student() { BirthDate = DateTime.UtcNow.AddYears(-13), ClassId = 1, Grade = 2, Name = "李四", TotalScore = 198 };
var student3 = new Student() { BirthDate = DateTime.UtcNow.AddYears(-13), ClassId = 2, Grade = 2, Name = "王五", TotalScore = 197 };
var student4 = new Student() { BirthDate = DateTime.UtcNow.AddYears(-13), ClassId = 2, Grade = 2, Name = "赵七", TotalScore = 196 };
var student5 = new Student() { BirthDate = DateTime.UtcNow.AddYears(-13), ClassId = 2, Grade = 2, Name = "狗蛋", TotalScore = 195 };
var student6 = new Student() { BirthDate = DateTime.UtcNow.AddYears(-13), ClassId = 2, Grade = 2, Name = "江小牙", TotalScore = 180 };
//这个学生没有班级
var student7 = new Student() { BirthDate = DateTime.UtcNow.AddYears(-13), ClassId = null, Grade = 2, Name = "孙小空", TotalScore = 199 };
return new List<Student>() { student1, student2, student3, student4, student5, student6, student7 };
}
通常情况下,如果按照规范来写的话,我们是不需要手动进行关系配置的。
但是有需要的话我们也可以手动进行关系配置。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>().Property(x => x.Name).HasMaxLength(50);
modelBuilder.Entity<Student>()
.HasOne<Class>(s => s.Class)
.WithMany(ad => ad.Students)
//外键的可以是其它的属性名不符合 entity+Id的格式
.HasForeignKey(x => x.ClassId);
base.OnModelCreating(modelBuilder);
}
上面的完整代码可以在分支relationship/one_to_many
看到
git clone https://gitee.com/malema/Examples
git checkout relationship/one_to_many
OneToManyExample.cs