这可能与Dapper有关吗?

时间:2014-03-20 15:56:07

标签: sql sql-server dapper

如果您的Customer对象具有List<Orders>属性,您如何选择所需的客户,然后将该客户的订单应用于每个客户的List<Orders>属性?

我能想到的唯一方法是循环客户并针对该客户的相关订单点击数据库N次。

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

1 个答案:

答案 0 :(得分:2)

您应该使用多映射。来自Dapper文档:

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);

在您的代码中,用户将是客户,订单将是帖子

编辑我意识到这并不是您想要的。因此,在您的情况下,您可以使用QueryMultiple,但然后将两个列表中的记录与linq匹配,避免达到Db N次:

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()
}
如果您在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()
}