Dapper MultiMap不适用于具有NULL值的splitOn

Jak*_*cki 17 dapper

我在dapper试图拆分包含的列时出现MultiMaps问题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();
    }
Run Code Online (Sandbox Code Playgroud)

失败的行是product.Category.IsNotNull();由于cat传递给映射函数的事实null.

我还将此方法添加到Assert类:

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

Sam*_*ron 18

这是"按设计",虽然我可以重新审视它.

特别是这种行为可以帮助左连接.以此为例:

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

麻烦的是,如果我们允许"毯子"创建一个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();
Run Code Online (Sandbox Code Playgroud)

  • 我刚遇到这个问题,并且没有提前知道这种行为.我有兴趣至少有一个`splitOnNull:true`标志来避免这个问题.在那之前必须使用代理列. (2认同)