Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dapper multi-mapping not returning null object when splitOn column is not in child object

Tags:

dapper

I'm using dapper 1.50.2 with MySQL and running into a problem trying to map a left outer join child object to its parent. If I split on a column alias that doesn't actually exist in the child object, Dapper always creates a child object with default properties, even when there is nothing in the left join.

I created a simple example to demonstrate this:

public class ParentRecord
{
    public string MemberID { get; set; }
    public ChildRecord Child { get; set; }
}

public class ChildRecord
{
    //public string Split { get; set; }
    public string SomeField { get; set; }
}

using (MySqlConnection connection = new MySqlConnection(connectionString))
{
    ParentRecord result = connection.Query<ParentRecord, ChildRecord, ParentRecord>(
    @"SELECT 'FakeID' AS MemberID, NULL AS Split, NULL AS SomeField",
        (mt, crt) =>
        {
            mt.Child = crt;
            return mt;
        },
        splitOn: "Split").Single();
}

I would expect this to result a ParentRecord with the Child property set to null, but the Child property is set to a ChildRecord with all default fields.

If I uncomment the Split property in ChildRecord, or if I split on SomeField, this works as I'd expect.

Are there any good workarounds for this?

In the actual query I'm dealing with, there are multiple primary key and foreign key fields with the same names and I'd rather not change the property names in the POCOs to be unique. I'd prefer to be able to use column aliases that are just there to split on. I know this isn't normally how Dapper is set to up to work.

Any help would be appreciated, thanks.

like image 666
TheCommunistCow Avatar asked Nov 09 '22 01:11

TheCommunistCow


1 Answers

This happen because the object Child initialize for default when you attribute the ctr param. Then the solution that I did implement was:

ParentRecord result = connection.Query<ParentRecord, ChildRecord, ParentRecord>(
    @"SELECT 'FakeID' AS MemberID, NULL AS Split, NULL AS SomeField",
        (mt, crt) =>
        {
            if (crt.SomeField != null){ mt.Child = crt; }
            return mt;
        },
        splitOn: "Split").Single();
like image 124
Alexandro Pinheiro Avatar answered Jan 04 '23 03:01

Alexandro Pinheiro