Wie wählt man eins zu viele Beziehung & eins zu eins zusammen mit Dapper

dapper one-to-many one-to-one select

Frage

Ich habe folgende Klassen und DB Schema. Ich versuche, diese Daten aus der Datenbank mit Dapper abzufragen, die das vollständige Objektdiagramm hydratisieren würde. Ich schaute mir verschiedene SO-Fragen und den Test an, konnte aber nicht wirklich herausfinden, wie das geht.

DB-Schema

Author
  -AuthorId
  -Name

Post
  -PostId
  -Content
  -AuthorId

Comment
  -PostId
  -CommentId
  -Content

Tag
  -PostId
  -TagId
  -Name

Klassen

public class Author
{
    public int AuthorId { get; set; }
    public string Name { get; set; }
}

public class Tag
{
    public int PostId { get; set; }
    public int TagId { get; set; }
    public string Name { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Content { get; set; }
    public int AuthorId { get; set; }
    public List<Tag> Tags { get; set; }
    public List<Comment> Comments { get; set; }
    public Author Author { get; set; }

    public Post()
    {
        this.Comments = new List<Comment>();
        this.Tags = new List<Tag>();
    }
}

public class Comment
{
    public int PostId { get; set; }
    public int CommentId { get; set; }
    public string Content { get; set; }
}

Akzeptierte Antwort

Also habe ich etwas wie das folgende gemacht.

public static IEnumerable<Post> Map(this SqlMapper.GridReader reader, Func<Post, int> postKey, Func<Comment, int> commentKey, Func<Tag, int> TagKey, Action<Post, IEnumerable<Comment>> addPostComment, Action<Post, IEnumerable<Tag>> addPostTag)
{
    var posts = reader.Read<Post>().ToList();
    var comments = reader.Read<Comment>().GroupBy(t => commentKey(t)).ToDictionary(g => g.Key, g => g.AsEnumerable());
    var tags = reader.Read<Tag>().GroupBy(t => TagKey(t)).ToDictionary(g => g.Key, g => g.AsEnumerable());
    var authors = reader.Read<Author>().ToList();

    foreach (var post in posts)
    {
        IEnumerable<Tag> posttags;
        if (tags.TryGetValue(postKey(post), out posttags))
        {
            addPostTag(post, posttags);
        }

        IEnumerable<Comment> postcomments;
        if (comments.TryGetValue(postKey(post), out postcomments))
        {
            addPostComment(post, postcomments);
        }

        post.Author = authors.Where(a => a.AuthorId == post.AuthorId).SingleOrDefault();
    }
    return posts;
}

Verwenden Sie die obige Erweiterung wie folgt.

        var query = "SELECT p.* FROM Post p " +
                    "SELECT c.* FROM Comment c WHERE c.PostId in ( SELECT PostId FROM Post) " +
                    "SELECT t.* FROM Tag t WHERE t.PostId in ( SELECT PostId FROM Post) " +
                    "SELECT a.* FROM Author a WHERE a.AuthorId in ( SELECT AuthorId FROM Post) ";
        List<Post> result = new List<Post>();
        using (var conn = new System.Data.SqlClient.SqlConnection(ConnectionString))
        {
            conn.Open();
            try
            {
                var posts = conn.QueryMultiple(query)
                            .Map
                            (
                                p => p.PostId,
                                c => c.PostId,
                                t => t.PostId,
                                (p, c) => p.Comments.AddRange(c),
                                (p, t) => p.Tags.AddRange(t)
                            );
                if (posts != null && posts.Any())
                {
                    result.AddRange(posts);
                }
            }
            catch (Exception)
            {
                //TODO: Log Exception
                throw;
            }
            conn.Close();
        }


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum