Mapping Dapper-Abfrage auf eine Sammlung von Objekten (die selbst ein paar Sammlungen hat)

dapper multi-mapping

Frage

Ich möchte eine einzelne Abfrage (oder Stored Proc mit mehreren Resultsets) ausführen. Ich weiß, wie man Multi-Mapping mit Dapper macht, aber ich kann nicht sortieren, wie man die beiden Sammlungen auf den gleichen Elternteil abbildet. Grundsätzlich, angesichts dieser Objektdefinition ...

class ParentObject
{
    string Name { get; set; }
    ICollection<ChildObjectOne> ChildSetOne {get;set;}
    ICollection<ChildObjectTwo> ChildSetTwo { get; set; }
}

class ChildObjectOne
{
    string Name { get; set; }
}

class ChildObjectTwo
{
    int id { get; set; }
    string LocationName { get; set; }
}

Ich möchte in der Lage sein, eine Dapper-Abfrage auszuführen, die irgendwie ergibt:

IQueryable<ParentObject> result = cnn.Query(
          // Some really awesome dapper syntax goes here
);

Akzeptierte Antwort

Ich bin mir nicht sicher, ob Sie das MultiMapping NICHT verwenden möchten, aber so würde es für Ihren Fall funktionieren. Soweit ich SO kenne und lese, ist es nicht möglich, einen tief verschachtelten Objektgraphen mit einer einfachen Query abzubilden.

 static void Main(string[] args)
        {
            var sqlParent = "SELECT parentId as Id FROM ParentTable WHERE parentId=1;";
            var sqlChildOneSet = "SELECT Name FROM ChildOneTable;"; // Add an appropriate WHERE
            var sqlChildTwoSet = "SELECT Id, LocationName FROM ChildTwoTable;"; // Add an appropriate WHERE

            var conn = GetConnection() // whatever you're getting connections with
            using (conn)
            {
                conn.Open();
                using (var multi = conn.QueryMultiple(sqlParent + sqlChildOneSet + sqlChildTwoSet))
                {
                    var parent = multi.Read<ParentObject>().First();
                    parent.ChildSetOne = multi.Read<ChildOne>().ToList();
                    parent.ChildSetTwo = multi.Read<ChildTwo>().ToList();
                }
            }
        }

Ähnliche Fragen für verschachtelte Objekte und Dapper:

https://stackoverflow.com/search?q=nested+objects+%2B+dapper


Beliebte Antwort

Es ist möglich, ein Objekt mit 1: IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map); -Beziehungen zu materialisieren, indem die IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map); Methode in diesem Fall. Sie müssen jedoch einige Änderungen an den Entitäten vornehmen, um genügend Informationen dafür zu haben.

Hier sind ein paar SO-Threads mit ähnlichen Fragen.

Wie ordne ich Listen von verschachtelten Objekten mit Dapper zu

Erweiterungsfunktion, um es sauberer zu machen

Dapper.Net am Beispiel - Mapping-Beziehungen

public class ParentObject
{
    public ParentObject()
    {
        ChildSetOne = new List<ChildObjectOne>();
        ChildSetTwo = new List<ChildObjectTwo>();
    }
    // 1) Although its possible to do this without this Id property, For sanity it is advisable.
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<ChildObjectOne> ChildSetOne {get; private set;}
    public ICollection<ChildObjectTwo> ChildSetTwo { get; private set; }
}

public class ChildObjectOne
{
    // 2a) Need a ParentId
    public int ParentId { get; set; }
    public string Name { get; set; }
}

public class ChildObjectTwo
{
    // 2b) This ParentId is not required but again for sanity it is advisable to include it.
    public int ParentId { get; set; }
    public int id { get; set; }
    public string LocationName { get; set; }
}

public class Repository
{
    public IEnumerable<ParentObject> Get()
    {
        string sql = 
            @"SELECT 
                p.Id, 
                p.Name, 
                o.Name, 
                o.ParentId, 
                t.Id, 
                t.LocationName, 
                t.ParentId 
            FROM 
                Parent p 
                    LEFT JOIN ChildOne o on o.ParentId = p.Id 
                    LEFT JOIN ChildTwo t on t.ParentId = p.Id 
            WHERE 
                p.Name LIKE '%Something%'";

        var lookup = new Dictionary<int, ParentObject>();
        using (var connection = CreateConnection())
        {

            connection.Query<ParentObject, ChildObjectOne, ChildObjectTwo, ParentObject>(
                sql, (parent, childOne, childTwo) =>
                {
                    ParentObject activeParent;

                    if (!lookup.TryGetValue(childOne.ParentId, out activeParent)) 
                    {
                        activeParent = parent;
                        lookup.add(activeParent.Id, activeParent);
                    }

                    //TODO: if you need to check for duplicates or null do so here
                    activeParent.ChildSetOne.Add(childOne);

                    //TODO: if you need to check for duplicates or null do so here
                    activeParent.ChildSetTwo.Add(childTwo);

                });   
        }
        return lookup.Values;
    }
}


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