Is this possible with Dapper?

dapper sql sql-server

Question

If you have a Customer object that has a List<Orders> property how can you select the customers you want and then apply the orders for that customer to the List<Orders> property for each one?

The only way I can think is to loop over customers and hit the database N times for the relevant orders against that customer.

var sql = @"
select * from Customers
select * from Orders where CustomerId = @id";

using (var multi = connection.QueryMultiple(sql))
{
   var customers = multi.Read<Customer>();

   //Get orders for each result in customers and apply 
   //Customer.Orders property to result
   var orders = multi.Read<Order>().ToList();
} 

Accepted Answer

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()
}


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why