.NET CORE:Dapper 映射多对多查询
Posted
技术标签:
【中文标题】.NET CORE:Dapper 映射多对多查询【英文标题】:.NET CORE: Dapper map many-to-many query 【发布时间】:2020-12-19 19:47:14 【问题描述】:我正在尝试学习 Dapper,但我一直在尝试将查询映射到多对多关系。在这种情况下,我有三个模型和各自的表,CourseModel、StudentCourseModel 和 StudentViewModel。
我正在尝试创建一个详细视图,您可以在其中显示学生及其正在参加的所有课程。这就是我尝试访问数据的方式,但由于某种原因,即使学生参加的课程多于课程,学生课程列表中也只设置了一条“课程”记录。我究竟做错了什么?谢谢!
课程模型
public class CourseModel
public int Id get; set;
public string CourseCode get; set;
public string CourseName get; set;
public string CourseDescription get; set;
StudentCourseModel
public class StudentCourseModel
public int Id get; set;
public int StudentId get; set;
public int CourseId get; set;
StudentViewModel
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 async Task<IActionResult> Details(int id)
using (IDbConnection cnn = new SqlConnection("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=SchoolSystemDB;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"))
var p = new
Id = id
;
string sql = $@"select dbo.Students.*, dbo.Courses.*
from dbo.Students
INNER JOIN[dbo].[StudentCourses] ON dbo.StudentCourses.StudentID = dbo.Students.Id
INNER JOIN[dbo].[Courses] ON dbo.Courses.Id = dbo.StudentCourses.CourseId
WHERE dbo.Students.Id = @Id";
StudentViewModel student = cnn.Query<StudentViewModel, CourseModel, StudentViewModel>(sql,
(StudentViewModel, CourseModel) =>
StudentViewModel.Courses.Add(CourseModel);
return StudentViewModel;
,
p).First();
return View(student);
【问题讨论】:
在 StudentViewModel 构造函数中设置断点。我的猜测是每个 CourseModel 实例都会调用它。见dapper-tutorial.net/query 【参考方案1】:在学习使用 dapper 的过程中,我还在处理多对多映射问题。
对我来说,以下过程证明是有帮助的:
在构建映射函数时,您在 SSMS 等数据库建模工具中执行一次查询,以查看查询数据的结构。
然后您可以想象,对于查询结果中返回的每一行,都会执行映射函数。因此,您需要跟踪映射函数已处理的数据。传递给函数的 StudentViewModel 实例代表当前行之一,这解释了为什么您只附加了一个课程。
要跟踪学生,您可以在映射功能之外使用查找字典。 (无法测试 atm 以下的样本)
var studentLookup = new Dictionary<int, StudentViewModel>();
var res = cnn
.Query<StudentViewModel, CourseModel, StudentViewModel>(
sql,
(svm, cm) =>
// Check if the student was already processed; if so, retrieve the reference
if (!studentLookup.TryGetValue(svm.Id, out var student))
student = svm;
studentLookup.Add(svm.Id, student);
// add course to the student that is assigned with the current record
if (svm.Courses == null)
svm.Courses = new List<CourseModel>();
if (svm.Courses.All(x => x.Id != cm.Id))
svm.Courses.Add(cm);
return svm;
,
new Id = id );
【讨论】:
以上是关于.NET CORE:Dapper 映射多对多查询的主要内容,如果未能解决你的问题,请参考以下文章