Looking for dapper Keywords? Try Ask4Keywords

Dapper.NET Отображение «один ко многим»


пример

Давайте рассмотрим более сложный пример, содержащий отношения «один ко многим». Теперь наш запрос будет содержать несколько строк, содержащих повторяющиеся данные, и нам нужно будет справиться с этим. Мы делаем это с поиском в закрытии.

Запрос слегка меняется, как и классы примеров.

Я бы название Родившийся CountryId Название страны BookID BookName
1 Даниэль Деннетт 1942 1 Соединенные Штаты Америки 1 Мозговые штурмы
1 Даниэль Деннетт 1942 1 Соединенные Штаты Америки 2 Колено
2 Сэм Харрис 1967 1 Соединенные Штаты Америки 3 Моральный пейзаж
2 Сэм Харрис 1967 1 Соединенные Штаты Америки 4 Пробуждение: руководство к духовности без религии
3 Ричард Докинз 1941 2 Объединенное Королевство 5 Магия реальности: как мы знаем, что действительно верно
3 Ричард Докинз 1941 2 Объединенное Королевство 6 Аппетит к удивлению: создание учёного
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; }
}

Словарь, remainingHorsemen всадниках, будет заполнен полностью материализованными экземплярами объектов человека. Для каждой строки результата запроса передаются сопоставленные значения экземпляров типов, определенных в аргументах лямбда, и вам решать, как справиться с этим.

            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");

Обратите внимание, как аргумент splitOn представляет собой список с разделителями-запятыми из первых столбцов следующего типа.