EFCore-13 多对多关系配置

学生与老师的关系,是一个常见的多对多的关系模型,一个老师有多个学生,一个学生也可能有多个老师。关系模型图如下所示:

学生1的老师为老师1、老师2

学生2的老师为老师2、老师3

学生3的老师为老师1、老师2、老师3

下面用程序实现这样的关系模型。

新建一个控制台应用程序

控制台项目结构:

项目引用的程序集:

Microsoft.EntityFrameworkCore.SqlServer 

Microsoft.EntityFrameworkCore.Tools 

1.在实体类中定义关系属性

Student.cs

using System.Collections.Generic;

namespace 多对多
{
    /// <summary>
    /// 学生实体
    /// </summary>
    class Student
    {
        public long Id { get; set; }

        public string Name { get; set; }

        public List<Teacher> Teachers { get; set; } = new List<Teacher>();
    }
}

Teacher.cs

using System.Collections.Generic;

namespace 多对多
{
    /// <summary>
    /// 老师实体
    /// </summary>
    class Teacher
    {
        public long Id { get; set; }

        public string Name { get; set; }

        public List<Student> Students { get; set; } = new List<Student>();
    }
}

2.FluentAPI关系配置

StudentConfig.cs

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace 多对多
{
    class StudentConfig : IEntityTypeConfiguration<Student>
    {
        public void Configure(EntityTypeBuilder<Student> builder)
        {
            builder.ToTable("T_Students");
            //配置学生与老师的多对多关系,并指定中间关系表的表名
            builder.HasMany<Teacher>(s => s.Teachers).WithMany(t => t.Students).UsingEntity(j => j.ToTable("T_Students_Teachers"));
        }
    }
}

TeacherConfig.cs

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace 多对多
{
    class TeacherConfig : IEntityTypeConfiguration<Teacher>
    {
        public void Configure(EntityTypeBuilder<Teacher> builder)
        {
            builder.ToTable("T_Teachers");
        }
    }
}

3.DbContext配置

用于定义数据库表和数据库链接等信息

MyDbContext.cs

using Microsoft.EntityFrameworkCore;

namespace 多对多
{
    class MyDbContext : DbContext
    {

        public DbSet<Student> students { get; set; }
        public DbSet<Teacher> teachers { get; set; }


        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);

            string connStr = "Server=.;Database=EFCoreDemo2;Trusted_Connection=True;MultipleActiveResultSets=true";
            optionsBuilder.UseSqlServer(connStr);


            //打印log日志
            //optionsBuilder.LogTo(msg =>
            //{
            //    if (msg.Contains("CommandExecuting"))
            //    {
            //        Console.WriteLine(msg);
            //    }
            //    else
            //    {
            //        return;
            //    }
            //});
        }



        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            //从当前程序集加载所有IEntityTypeConfiguration
            modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);
        }
    }
}

4.生成并执行数据库迁移脚本

使用命令生成数据库表创建脚本,并执行相关脚本。具体操作参考文章

EFCore-5 Migration操作

 这里要注意下,虽然在代码中只定义了两个实体类,但是在StudentConfig.cs中配置的关系为多对多,所以efcore会自动生成一张中间关系表,用来记录两个表数据的对应关系。

中间关系表字段信息如下:

记录了两个表的主键字段值

5.往数据库表插入记录

using Microsoft.EntityFrameworkCore;
using System;
using System.Threading.Tasks;

namespace 多对多
{
    class Program
    {
        static async Task Main(string[] args)
        {
            //插入数据
            using (MyDbContext ctx = new MyDbContext())
            {
                Student s1 = new Student() { Name = "张三" };
                Student s2 = new Student() { Name = "李四" };
                Student s3 = new Student() { Name = "王五" };

                Teacher t1 = new Teacher() { Name = "Tom" };
                Teacher t2 = new Teacher() { Name = "Jerry" };
                Teacher t3 = new Teacher() { Name = "Zack" };

                s1.Teachers.Add(t1);
                s1.Teachers.Add(t2);

                s2.Teachers.Add(t2);
                s2.Teachers.Add(t3);

                s3.Teachers.Add(t1);
                s3.Teachers.Add(t2);
                s3.Teachers.Add(t3);

                ctx.students.Add(s1);
                ctx.students.Add(s2);
                ctx.students.Add(s3);

                ctx.teachers.Add(t1);
                ctx.teachers.Add(t2);
                ctx.teachers.Add(t3);

                await ctx.SaveChangesAsync();
            }
          
        }
    }
}

 查询数据库表记录

 6.查询所有老师,并查询老师对应的学生

using Microsoft.EntityFrameworkCore;
using System;
using System.Threading.Tasks;

namespace 多对多
{
    class Program
    {
        static async Task Main(string[] args)
        {
            //查询所有老师,并查询老师对应的学生
            using (MyDbContext ctx = new MyDbContext())
            {
                var teachers = ctx.teachers.Include(t => t.Students);
                foreach (var t in teachers)
                {
                    Console.WriteLine(t.Name);
                    foreach (var s in t.Students)
                    {
                        Console.WriteLine("\t" + s.Name);
                    }
                }
            }
        }
    }
}

执行结果:

 打印出老师的名字和老师对应学生的名字。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值