Dapper-多表查询详解 (一对一、一对多、多对多关联查询)
一对一和一对多,使用书本、作者、书签 作为示例: 一本书只有一个作者,并且有多条书签
实体类:
public class BookMark { public int Id { get; set; } public int BookId { get; set; } public virtual string Content { get; set; } }
public class Book { public Book() { Marks = new List<BookMark>(); } public int Id { get; set; } public string Name { get; set; } public Author Author { get; set; } public virtual List<BookReview> Marks { get; set; } }
public class Author { public int Id { get; set; } public string Name { get; set; }
public string BookId { get; set; } }
关联查询的方法
先查看一下Dapper的源码,SqlMapper类; 使用这类的泛型方法:
可以看出SqlMapper类对IDbConnection做出了拓展方法,并针对不同的关联数量实现了不同的重载方法。
其中First、 Second、 Third.........等等泛型参数代表需要关联的对象。可以看出最多可以传入6个泛型参数,支持到TFifth, 也就是最多支持到关联五个表。
相对于单表查询,主要多了一个Func<>泛型内置委托,委托类型与方法泛型参数一致,映射对应关系的逻辑代码应该写在这个泛型委托中
一路f12就可以跟踪到这个委托最终调用的地方
大致简单的知道了原理和流程,开始示例代码:
一对一关联
书本与作者一对一关联:
public Book GetEntity(string id) { using (Conn) { string query = "SELECT * FROM Book b INNER JOIN Author au ON au.BookId = b.Id WHERE b.id = @id"; Book lookup = null; var b = Conn.Query<Book, Author, Book>(query, (book, author) => { if (author != null) lookup.Author = author; return lookup; }, new { id = id }).Distinct().SingleOrDefault(); return b; } }
非常简单,直接在委托中赋值即可。
一对多关联
书本与书签一对多关联:
public Book GetEntityWithRefence(string id) { using (Conn) { string query = "SELECT * FROM Book b LEFT JOIN BookMark bm ON bm.BookId = b.Id WHERE b.id = @id"; Book lookup = null; var b = Conn.Query<Book, BookMark, Book>(query, (book, bookMark) => { if (lookup == null || lookup.Id != book.Id) lookup = book; if (bookMark != null) lookup.Marks.Add(bookMark); return lookup; }, new { id = id }).Distinct().SingleOrDefault(); return b; } }
因为是IList, 所以使用Add的方式添加到主表。
多对多同一对多的写法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)