20

我在 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();的事实是.catnull

我还在 Assert 类中添加了这个方法:

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

3 回答 3

21

这是“设计使然”,尽管我可以重新审视它。

特别是这种行为有助于左连接。以此为例:

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();
于 2012-05-29T00:04:04.737 回答
3

对于所有想要可视化的人:

Dapper 按最后一个相等的列名拆分:

在此处输入图像描述

让我们交换列的位置:

在此处输入图像描述

空问题:

在此处输入图像描述

交换列 null :

在此处输入图像描述

斯普利顿救援:

在此处输入图像描述

于 2017-02-12T10:45:52.297 回答
2

我有同样的问题,我不得不选择一个假的“拆分”列来让 Dapper 填充我的对象,而不是仅仅为空它;

我的解决方法:

    string req = @"
SELECT
    T1.a as PropA,
    T1.b as PropB,

    1 as Split,
    T2.a as PropA,
    T2.b as PropB,

    1 as Split,
    ...
FROM
    xxx T1,
    yyy T2,
    ...";
    using (var db = new OracleConnection(...))
    {
        return db.Query(
            req,
            (T1, T2) => {
                ...
            },
            splitOn:'Split,Split,...');
    }

Dapper 应该有一个选项来避免splitOn:'Split,Split,...'

于 2018-09-11T15:53:12.457 回答