You should use multi-mapping. From Dapper documentation:
var sql =
@"select * from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id";
var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});
var post = data.First();
post.Content.IsEqualTo("Sams Post1");
post.Id.IsEqualTo(1);
post.Owner.Name.IsEqualTo("Sam");
post.Owner.Id.IsEqualTo(99);
In your code Users will be Customers, and Orders will be Posts
Edit I realize that this is not exactly what your want. So, in your case you can use QueryMultiple, but then matching the records from both lists with linq, avoiding hitting the Db N times:
var sql = @"select * from Customers
select * from Orders";
using (var multi = connection.QueryMultiple(sql))
{
var customer = multi.Read<Customer>().Single();
var orders = multi.Read<Order>().ToList();
}
foreach c in customers {
c.Orders = (from rec in orders where rec.CustomerId == c.Id select rec).ToList()
}
Edit refactor for better performance if you have several filter in Customers
var customers = connection.Query<Customer>("select * from Customers
where blah, blah, blah, blah, .. ").ToList();
var orders = connection.Query<Order>("select * from Order where CustomerID in @Ids",
new { Ids = (from rec in customers select rec.Id).ToList()}).ToList();
foreach c in customers {
c.Orders = (from rec in orders where rec.CustomerId == c.Id select rec).ToList()
}