Hi I have the following classes (simplified) I want dapper to map to
Member.cs
public string FirstName { get; set; }
public string LastName { get; set; }
public Place Address { get; set; }
Place.cs
public string Address{ get; set; }
public string City { get; set; }
public string PostalZip { get; set; }
The response I get from the SQL server looks like:
Id FirstName LastName AddressAddress AddressCity
-----------------------------------------------------------------------------
113 First Last Some Address Some City
When i execute this:
var members = session.Connection.Query<Member>(dataQuery, p, transaction).ToList();
It maps the Member part just fine, but the Address property on the Member (place.cs) remains unmapped, how to I tell dapper how to map it?
Assuming that PostalZip is not a Place type but probably a simple string then your Dapper query could be made as
using (IDbConnection connection = OpenConnection())
{
string query = @"SELECT Id,FirstName,LastName,
0 as splitterID, Address, City, PostalZip
FROM Members";
var result = connection.Query<Member, Place, Member>(query, (mb, pl) =>
{
mb.Address = pl;
return mb;
},
splitOn: "splitterID");
}
This query returns all the records of the Members
table into an IEnumerable<Member>
variable. Each element of the IEnumerable (a Member) has its Address field set up as a Place with Address, City and PostalCode extracted from the second part of the record.
The trick lies in the lambda expression passed to the Query method. Here we declare it to be a Func receiving a Member and a Place from the Dapper internals an returning a Member.
The Dapper library understands the need to create an instance of the Place type when it finds the fake field splitterID
defined by the parameter splitOn
and pass this instance to the lambda together with the Member instance.
The lambda expression assigns the instance of Place to the property Address of the Member instance and return the same Member instance correctly initialized.
( I was not able to split directly with the Address field and will be curious to know if there is a way to do it without a fake field)