Dapper.NET One-to-Many-Zuordnung


Beispiel

Schauen wir uns ein komplexeres Beispiel an, das eine Eins-zu-Viele-Beziehung enthält. Unsere Abfrage enthält jetzt mehrere Zeilen, die doppelte Daten enthalten, und wir müssen dies behandeln. Wir machen das mit einem Lookup in einem Abschluss.

Die Abfrage ändert sich geringfügig wie die Beispielklassen.

Ich würde Name Geboren CountryId Ländername BookId BookName
1 Daniel Dennett 1942 1 vereinigte Staaten von Amerika 1 Brainstorms
1 Daniel Dennett 1942 1 vereinigte Staaten von Amerika 2 Spielraum
2 Sam Harris 1967 1 vereinigte Staaten von Amerika 3 Die moralische Landschaft
2 Sam Harris 1967 1 vereinigte Staaten von Amerika 4 Aufwachen: Ein Leitfaden für Spiritualität ohne Religion
3 Richard Dawkins 1941 2 Großbritannien 5 Die Magie der Realität: Wie wir wissen, was wirklich wahr ist
3 Richard Dawkins 1941 2 Großbritannien 6 Appetit for Wonder: Die Entstehung eines Wissenschaftlers
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Born { get; set; }
    public Country Residience { get; set; }
    public ICollection<Book> Books { get; set; }
}

public class Country
{
    public int CountryId { get; set; }
    public string CountryName { get; set; }
}

public class Book
{
    public int BookId { get; set; }
    public string BookName { get; set; }
}

Das remainingHorsemen WörterbuchHorsemen wird mit vollständig materialisierten Instanzen der Personenobjekte gefüllt. Für jede Zeile des Abfrageergebnisses werden die zugeordneten Werte von Instanzen der in den Lambda-Argumenten definierten Typen übergeben, und es liegt an Ihnen, wie Sie damit umgehen.

            var sql = @"SELECT 1 AS Id, 'Daniel Dennett' AS Name, 1942 AS Born, 1 AS CountryId, 'United States of America' AS CountryName, 1 AS BookId, 'Brainstorms' AS BookName
UNION ALL SELECT 1 AS Id, 'Daniel Dennett' AS Name, 1942 AS Born, 1 AS CountryId, 'United States of America' AS CountryName, 2 AS BookId, 'Elbow Room' AS BookName
UNION ALL SELECT 2 AS Id, 'Sam Harris' AS Name, 1967 AS Born, 1 AS CountryId,  'United States of America' AS CountryName, 3 AS BookId, 'The Moral Landscape' AS BookName
UNION ALL SELECT 2 AS Id, 'Sam Harris' AS Name, 1967 AS Born, 1 AS CountryId,  'United States of America' AS CountryName, 4 AS BookId, 'Waking Up: A Guide to Spirituality Without Religion' AS BookName
UNION ALL SELECT 3 AS Id, 'Richard Dawkins' AS Name, 1941 AS Born, 2 AS CountryId,  'United Kingdom' AS CountryName, 5 AS BookId, 'The Magic of Reality: How We Know What`s Really True' AS BookName
UNION ALL SELECT 3 AS Id, 'Richard Dawkins' AS Name, 1941 AS Born, 2 AS CountryId,  'United Kingdom' AS CountryName, 6 AS BookId, 'An Appetite for Wonder: The Making of a Scientist' AS BookName";

var remainingHorsemen = new Dictionary<int, Person>();
connection.Query<Person, Country, Book, Person>(sql, (person, country, book) => {
    //person
    Person personEntity;
    //trip
    if (!remainingHorsemen.TryGetValue(person.Id, out personEntity))
    {
        remainingHorsemen.Add(person.Id, personEntity = person);
    }

    //country
    if(personEntity.Residience == null)
    {
        if (country == null)
        {
            country = new Country { CountryName = "" };
        }
        personEntity.Residience = country;
    }                    

    //books
    if(personEntity.Books == null)
    {
        personEntity.Books = new List<Book>();
    }

    if (book != null)
    {
        if (!personEntity.Books.Any(x => x.BookId == book.BookId))
        {
            personEntity.Books.Add(book);
        }
    }

    return personEntity;
}, 
splitOn: "CountryId,BookId");

Beachten Sie, dass das splitOn Argument eine durch Kommas getrennte Liste der ersten Spalten des nächsten Typs ist.