Dapper MultiMap не работает с splitOn со значением NULL

У меня проблема с MultiMaps в dapper, пытаясь разделить на столбец, содержащий NULL. Кажется, что Dapper не создает экземпляр объекта, и моя функция сопоставления получает NULL вместо объекта.

Здесь мое новое испытание:

    class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public Category Category { get; set; }
    }
    class Category
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
    }
    public void TestMultiMapWithSplitWithNullValue()
    {
        var sql = @"select 1 as id, 'abc' as name, NULL as description, 'def' as name";
        var product = connection.Query<Product, Category, Product>(sql, (prod, cat) =>
        {
            prod.Category = cat;
            return prod;
        }, splitOn: "description").First();
        // assertions
        product.Id.IsEqualTo(1);
        product.Name.IsEqualTo("abc");
        product.Category.IsNotNull();
        product.Category.Id.IsEqualTo(0);
        product.Category.Name.IsEqualTo("def");
        product.Category.Description.IsNull();
    }

Неверная строка product.Category.IsNotNull(); из-за того, что cat передана функции отображения NULL.

Я также добавил этот метод в класс Assert:

public static void IsNotNull(this object obj)
{
    if (obj == null)
    {
        throw new ApplicationException("Expected not null");
    }
}

Ответ 1

Это "по-дизайн", хотя я был бы готов пересмотреть его.

В частности, это поведение помогает левым объединениям. Возьмите это, например:

cnn.Query<Car,Driver>("select * from Cars c left join Drivers on c.Id = CarId",
   (c,d) => {c.Driver = d; return c;}) 

Проблема заключается в том, что если мы разрешим создание "оверлея" объекта Driver, каждый Car будет иметь теги Driver, в которых соединение завершилось неудачно.

Чтобы обойти, мы могли бы сканировать весь разбитый сегмент и обеспечить, чтобы ВСЕ значения были NULL перед отображением объекта NULL. Это будет иметь очень незначительное влияние на мультиформатор.

Чтобы обходной путь для вашего случая, вы можете вставить суррогатную колонку:

var sql = @"select 1 as id, 'abc' as name, '' as split, 
            NULL as description, 'def' as name";
    var product = connection.Query<Product, Category, Product>(sql, (prod, cat) =>
    {
        prod.Category = cat;
        return prod;
    }, splitOn: "split").First();

Ответ 2

Для всех, кто хочет визуализации:

Dapper разбивается на последнее имя равного столбца:

введите описание изображения здесь

Разрешить местоположение столбцов:

введите описание изображения здесь

null проблема:

введите описание изображения здесь

Помененный столбец null:

введите описание изображения здесь

Сплитон на помощь:

введите описание изображения здесь