Looking for dapper Answers? Try Ask4KnowledgeBase
Looking for dapper Keywords? Try Ask4Keywords

Dapper.NET Custom Mappings


Example

If the query column names do not match your classes you can setup mappings for types. This example demonstrates mapping using System.Data.Linq.Mapping.ColumnAttributeas well as a custom mapping.

The mappings only need to be setup once per type so set them on application startup or somewhere else that they are only initialized once.

Assuming the same query as the One-to-many example again and the classes refactored toward better names like so:

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
{
    [System.Data.Linq.Mapping.Column(Name = "CountryId")]
    public int Id { get; set; }

    [System.Data.Linq.Mapping.Column(Name = "CountryName")]
    public string Name { get; set; }
}

public class Book
{
    public int Id { get; set; }

    public string Name { get; set; }
}

Note how Book doesn't rely on ColumnAttribute but we would need to maintain the if statement

Now place this mapping code somewhere in your application where it is only executed once:

Dapper.SqlMapper.SetTypeMap(
    typeof(Country),
    new CustomPropertyTypeMap(
        typeof(Country),
        (type, columnName) =>
            type.GetProperties().FirstOrDefault(prop =>
                prop.GetCustomAttributes(false)
                    .OfType<System.Data.Linq.Mapping.ColumnAttribute>()
                    .Any(attr => attr.Name == columnName)))
);


var bookMap = new CustomPropertyTypeMap(
    typeof(Book),
    (type, columnName) =>
    {
        if(columnName == "BookId")
        {
            return type.GetProperty("Id");
        }

        if (columnName == "BookName")
        {
            return type.GetProperty("Name");
        }

        throw new InvalidOperationException($"No matching mapping for {columnName}");
    }        
);
Dapper.SqlMapper.SetTypeMap(typeof(Book), bookMap);

Then the query is executed using any of the previous Query<> examples.

A simpler way of adding the mappings is shown in this answer.