Sql .NET核心:简洁的映射多对多查询

Sql .NET核心:简洁的映射多对多查询,sql,asp.net,asp.net-core,mapping,dapper,Sql,Asp.net,Asp.net Core,Mapping,Dapper,我正在努力学习Dapper,我一直在尝试将查询映射到多对多关系。在本例中,我有三个模型和相应的表:CourseModel、StudentCourseModel和StudentViewModel 我正在尝试创建一个详细视图,您可以在其中显示一个学生所参加的所有课程。这就是我试图访问数据的方式,但由于某种原因,在学生课程列表中只设置了一条“课程”记录,即使学生参加的课程多于课程。我做错了什么?谢谢 CourseModel public class CourseModel {

我正在努力学习Dapper,我一直在尝试将查询映射到多对多关系。在本例中,我有三个模型和相应的表:CourseModel、StudentCourseModel和StudentViewModel

我正在尝试创建一个详细视图,您可以在其中显示一个学生所参加的所有课程。这就是我试图访问数据的方式,但由于某种原因,在学生课程列表中只设置了一条“课程”记录,即使学生参加的课程多于课程。我做错了什么?谢谢

CourseModel

    public class CourseModel
    {
        public int Id { get; set; }
        public string CourseCode { get; set; }
        public string CourseName { get; set; }
        public string CourseDescription{ get; set; }

    }
    public class StudentCourseModel
    {
        public int Id { get; set; }
        public int StudentId { get; set; }
        public int CourseId { get; set; }
    }
    public class StudentViewModel
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public List<CourseModel> Courses { get; set; }

        public StudentViewModel()
        {
            Courses = new List<CourseModel>();
        }
    }
StudentCourseModel

    public class CourseModel
    {
        public int Id { get; set; }
        public string CourseCode { get; set; }
        public string CourseName { get; set; }
        public string CourseDescription{ get; set; }

    }
    public class StudentCourseModel
    {
        public int Id { get; set; }
        public int StudentId { get; set; }
        public int CourseId { get; set; }
    }
    public class StudentViewModel
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public List<CourseModel> Courses { get; set; }

        public StudentViewModel()
        {
            Courses = new List<CourseModel>();
        }
    }
学生视图模型

    public class CourseModel
    {
        public int Id { get; set; }
        public string CourseCode { get; set; }
        public string CourseName { get; set; }
        public string CourseDescription{ get; set; }

    }
    public class StudentCourseModel
    {
        public int Id { get; set; }
        public int StudentId { get; set; }
        public int CourseId { get; set; }
    }
    public class StudentViewModel
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public List<CourseModel> Courses { get; set; }

        public StudentViewModel()
        {
            Courses = new List<CourseModel>();
        }
    }
公共类学生视图模型
{
公共int Id{get;set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共整数{get;set;}
公共列表课程{get;set;}
公共学生视图模型()
{
课程=新列表();
}
}
公共异步任务详细信息(int-id)
{
使用(IDbConnection cnn=new SqlConnection(“数据源=(localdb)\\MSSQLLocalDB;初始目录=SchoolSystemDB;集成安全性=True;连接超时=30;加密=False;信任服务器证书=False;应用程序内容=读写;多子网故障切换=False”))
{
var p=新
{
Id=Id
};
字符串sql=$@“选择dbo.Students.*,dbo.Courses*
来自dbo.学生
dbo.StudentCourses.StudentID=dbo.Students.Id上的内部联接[dbo].[StudentCourses]
dbo.Courses.Id=dbo.StudentCourses.CourseId上的内部联接[dbo].[Courses]
其中dbo.Students.Id=@Id”;
StudentViewModel student=cnn.Query(sql,
(学生视图模型、课程模型)=>
{
StudentViewModel.Courses.Add(CourseModel);
返回学生视图模型;
},
p) .First();
返回视图(学生);
}
}

在学习使用dapper时,我也在努力处理多对多映射

对我来说,以下程序证明是有用的:

构建映射函数时,可以在数据库建模工具(如SSMS)中执行一次查询,以查看查询数据的结构

然后,假设对查询结果中的每个返回行执行映射函数。因此,您需要跟踪映射函数已经处理的数据。传递到函数中的StudentViewModel实例表示当前行的实例,这解释了为什么只附加了一个课程

为了跟踪学生,可以在映射函数之外使用查找词典。(无法在atm下测试样本)

var studentLookup=newdictionary();
var res=cnn
.查询(
sql,
(svm,cm)=>
{
//检查学生是否已被处理;如果已处理,则检索参考
if(!studentLookup.TryGetValue(svm.Id,out var student))
{
学生=支持向量机;
studentLookup.Add(svm.Id,student);
}
//向分配有当前记录的学生添加课程
if(svm.Courses==null)
{
svm.Courses=新列表();
}
if(svm.Courses.All(x=>x.Id!=cm.Id))
{
svm.Courses.Add(cm);
}
返回支持向量机;
},
新的{Id=Id});

在StudentViewModel构造函数中设置断点。我的猜测是CourseModel的每个实例都会调用它。看见