简体   繁体   English

Dapper - 使用一对多和多对多关系的数据库查询创建对象

[英]Dapper - creating objects with queries on database with one-to-many and many-to-many relationships

I have an Sqlite database, for a which a partial schema is:我有一个 Sqlite 数据库,其部分架构是: 在此处输入图像描述

In the code, classes representing the data are as follows (simplified):在代码中,表示数据的类如下(简化):

public Book : Item
{
    public ICollection<Tag> Tags { get; set; }
    public ICollection<Author> Authors { get; set; }
    public Publisher publisher { get; set; }
    // other properties...
}

public class Publisher
{
    public ICollection<Book> Books { get; set; }
    // other properties...
}

public class Author
{
    public ICollection<Author> Authors { get; set; }
}

public class Tag
{
    public ICollection<Item> Items { get; set; }
}

I need to return an IEnumerable<Book> , with the Book objects containing all Author , Publisher and Tag data for each Book .我需要返回一个IEnumerable<Book> ,其中Book对象包含每个Book的所有AuthorPublisherTag数据。 Currently, I have the following code, which solves the problem of getting publisher data:目前,我有以下代码,它解决了获取发布者数据的问题:

public IEnumerable<Book> GetAllBooks()
{
    using (var db = new SqliteConnection(connectionString)
    {
        var sql = "SELECT * FROM Books as B " +
                  "INNER JOIN Publishers AS P On B.publisherId = P.id;";
        var allBooks = db.Query<Book, Publisher, Book>(sql, (book, publisher) =>
        {
             book.publisher = publisher;
             return book;
        });
        return allBooks;
    }
}

How to get the remaining data for a Book (ie Author and Tag data with the many-to-many relationships as seen in the schema)?如何获取一Book的剩余数据(即AuthorTag数据与架构中的多对多关系)?

It wouldn't be very efficient if you go querying book by book so my recommendation is to query first all Author (s) including their Book.id then query all Tag (s) including their Book.id and then use LINQ to match by Book.id over the results of those queries as follows:如果您逐本书查询 go 将不会非常有效,所以我的建议是首先查询所有Author ,包括他们的Book.id ,然后查询所有Tag ,包括他们的Book.id ,然后使用LINQ匹配Book.id在这些查询的结果上,如下所示:

 public IEnumerable<Book> GetAllBooks() { using (var db = new SqliteConnection(connectionString)) { var authorsSql = "SELECT A.*, B.id AS BookId FROM Books as B " + "INNER JOIN Book_Author AS B2A On B.id = B2A.bookId " + "INNER JOIN Author A On B2A.authorId = A.id;"; var allAuthorsWithBookId = db.Query<dynamic>(authorsSql).AsList(); var tagsSql = "SELECT T.*, B.id AS BookId FROM Books as B " + "INNER JOIN Book_Tag AS B2T On B.id = B2T.bookId " + "INNER JOIN Tags T On B2T.tagId = T.id;"; var allTagsWithBookId = db.Query<dynamic>(tagsSql).AsList(); var sql = "SELECT * FROM Books as B " + "INNER JOIN Publishers AS P On B.publisherId = P.id;"; var allBooks = db.Query<Book, Publisher, Book>(sql, (book, publisher) => { book.publisher = publisher; book.Authors = allAuthorsWithBookId.Where(row => row.BookId == book.id).Select(row => new Author{ id = row.id, name = row.name }).AsList(); book.Tags = allTagsWithBookId.Where(row => row.BookId == book.id).Select(row => new Tag{ id = row.id, name = row.name }).AsList(); return book; }); return allBooks; } }

You'll need to fix some typos and structural code (like a parenthesis at the end of the using ) and some missing properties in classes Author , Tag , etc. but it should be OK after that.您需要修复一些拼写错误和结构代码(例如using末尾的括号)以及AuthorTag等类中缺少的一些属性,但之后应该没问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM