一對一和一對多,使用書本、作者、書簽 作為示例: 一本書只有一個作者,並且有多條書簽
實體類:
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的方式添加到主表。
多對多同一對多的寫法