I've been playing around with this for a bit, because it seems like it feels a lot like the documented posts/users example, but its slightly different and isn't working for me.
Assuming the following simplified setup (a contact has multiple phone numbers):
public class Contact
{
public int ContactID { get; set; }
public string ContactName { get; set; }
public IEnumerable<Phone> Phones { get; set; }
}
public class Phone
{
public int PhoneId { get; set; }
public int ContactID { get; set; } // foreign key
public string Number { get; set; }
public string Type { get; set; }
public bool IsActive { get; set; }
}
I'd love to end up with something that returns a Contact with multiple Phone objects. That way, if I had 2 contacts, with 2 phones each, my SQL would return a join of those as a result set with 4 total rows. Then Dapper would pop out 2 contact objects with two phones each.
Here is the SQL in the stored procedure:
SELECT *
FROM Contacts
LEFT OUTER JOIN Phones ON Phones.ReferenceId=Contacts.ReferenceId
WHERE clientid=1
I tried this, but ended up with 4 Tuples (which is OK, but not what I was hoping for... it just means I still have to re-normalize the result):
var x = cn.Query<Contact, Phone, Tuple<Contact, Phone>>("sproc_Contacts_SelectByClient",
(co, ph) => Tuple.Create(co, ph),
splitOn: "PhoneId", param: p,
commandType: CommandType.StoredProcedure);
and when I try another method (below), I get an exception of "Unable to cast object of type 'System.Int32' to type 'System.Collections.Generic.IEnumerable`1[Phone]'."
var x = cn.Query<Contact, IEnumerable<Phone>, Contact>("sproc_Contacts_SelectByClient",
(co, ph) => { co.Phones = ph; return co; },
splitOn: "PhoneId", param: p,
commandType: CommandType.StoredProcedure);
Am I just doing something wrong? It seems just like the posts/owner example, except that I'm going from the parent to the child instead of the child to the parent.
Thanks in advance
Here's a reusable solution that is pretty easy to use. It is a slight modification of Andrews answer.
Example usage