EFcore 领域模型与数据库表映射(一对一、一对多、多对多)

例子:学生、班级(一对多),学生、档案(一对一),学生、课程(多对多)

/// <summary>
/// 学生类
/// </summary>
public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public int ClassId { get; set; }
    //...

    public virtual Classes Classes { get; set; }
    public virtual Archives Archives { get; set; }
    public virtual ICollection<StudentCourse> StudentCourses { get; set; }
}
/// <summary>
/// 班级类
/// </summary>
public class Classes
{
    public int Id { get; set; }
    public string Name { get; set; }
    //...     

    public virtual ICollection<Student> Students { get; set; }
}
/// <summary>
/// 档案类
/// </summary>
public class Archives
{
    public int Id { get; set; }
    public string Code { get; set; }
    public string RegionSource { get; set; }

    public int StudentId { get; set; }
    //...

    public virtual Student Student { get; set; }
}
/// <summary>
/// 课程类
/// </summary>
public class Course
{
    public int Id { get; set; }
    public string Name { get; set; }
    //...
}
/// <summary>
/// 学生课程类
/// </summary>
public class StudentCourse
{
    public int Id { get; set; }
    public int StudentId { get; set; }
    public int CourseId { get; set; }
        
    public virtual Student Student { get; set; }
    public virtual Course Course { get; set; }
}

EFcore DbContext 配置映射

public class TestContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("server=.;database=Test;uid=sa;pwd=123");
        /**
            * 如果不开启懒加载,所有引用其他对象的地方都要手动 Include 
            */
        optionsBuilder.UseLazyLoadingProxies();
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Student>(entry =>
        {
            entry.ToTable("Student").HasKey(e => e.Id);
            /**
                * 学生、档案 一对一
                */
            entry.HasOne(e => e.Archives).WithOne(e => e.Student).HasPrincipalKey<Student>(e => e.Id).HasForeignKey<Archives>(e => e.StudentId);
            /**
                * 学生、班级 一对多
                */
            entry.HasOne(e => e.Classes).WithMany().HasForeignKey(e => e.ClassId);
        });

        modelBuilder.Entity<StudentCourse>(entry =>
        {
            entry.ToTable("StudentCourse").HasKey(e => e.Id);
            /**
                * 学生、课程 多对多
                */
            entry.HasOne(e => e.Student).WithMany(e => e.StudentCourses).HasForeignKey(e => e.StudentId);
            entry.HasOne(e => e.Course).WithMany().HasForeignKey(e => e.CourseId);
        });

        modelBuilder.Entity<Classes>(entry =>
        {
            entry.ToTable("Classes").HasKey(e => e.Id);
            /**
                * 学生、班级 多对一,想从Classes类里获取Students集合,需配置关系
                */
            entry.HasMany(e => e.Students).WithOne(e => e.Classes);
        });

        modelBuilder.Entity<Archives>(entry =>
        {
            entry.ToTable("Archives").HasKey(e => e.Id);
        });

        modelBuilder.Entity<Course>(entry =>
        {
            entry.ToTable("Course").HasKey(e => e.Id);
        });
    }
}

数据库表与测试数据

CREATE TABLE Student(
	Id INT PRIMARY KEY IDENTITY NOT NULL,
	Name NVARCHAR(20) NOT NULL,
	Age INT NOT NULL,
	ClassId INT
)

CREATE TABLE Classes(
	Id INT PRIMARY KEY IDENTITY NOT NULL,
	Name NVARCHAR(20) NOT NULL
)

CREATE TABLE Archives(
	Id INT PRIMARY KEY IDENTITY NOT NULL,
	Code NVARCHAR(50) NOT NULL,
	RegionSource NVARCHAR(100),
	StudentId INT NOT NULL
)

CREATE TABLE Course(
	Id INT PRIMARY KEY IDENTITY NOT NULL,
	Name NVARCHAR(20) NOT NULL
)

CREATE TABLE StudentCourse(
	Id INT PRIMARY KEY IDENTITY NOT NULL,
	StudentId INT NOT NULL,
	CourseId INT NOT NULL
)

INSERT INTO	dbo.Classes ( Name )       
VALUES  ( '自由班' ),( '严格班' ),( '神气班' )

INSERT INTO	dbo.Student ( Name, Age, ClassId )
VALUES  ( '张三', 20, 1 ),( '李四', 21, 1 ),( '王五', 22, 1 ),
		( '赵六', 23, 2 ),( '神七', 24, 2 ),
		( '王八', 25, 3 )

INSERT INTO	dbo.Archives ( Code, RegionSource, StudentId )
VALUES  ( 'BH00001', '广东', 1 ),( 'BH00002', '广西', 2 ),( 'BH00003', '湖南', 3 ),
		( 'BH00004', '湖北', 4 ),( 'BH00005', '上海', 5 ),
		( 'BH00006', '天津', 6 )
		
INSERT INTO	dbo.Course ( Name )
VALUES  ( 'C#从入门到精通' ),( 'mysql从删库到跑路' ),( 'linux进阶' )

INSERT INTO	dbo.StudentCourse ( StudentId, CourseId )
VALUES  ( 1, 1 ),( 1, 2 ),( 1, 3 ),( 2, 1 ),( 2, 2 ),( 3, 2 )

测试结果:

static void Main(string[] args)
{
    TestContext context = new TestContext();

    foreach (var item in context.Set<Student>())
    {
        Console.WriteLine(item.Id + "," + item.Name + "," + item.Age + "," + item.Archives.Code + "," + item.Classes.Name + "," + string.Join(",", item.StudentCourses.Select(c => c.Course.Name)));
    }

    Console.WriteLine("=============================================");

    foreach (var item in context.Set<Classes>())
    {
        Console.WriteLine(item.Id + "," + item.Name + "," + string.Join(",", item.Students.Select(s => s.Name)));
    }
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值