Dapper seleccionando objetos anidados

c# dapper micro-orm orm sql-server

Pregunta

Mi SQL parece

Select TOP 3 o.OrderId,
o.Total,
od.Quantity,
od.ItemDescription,
os.OrderStatusDescription,
os.OrderStatusID
 From dbo.Orders o
 INNER JOIN dbo.OrderStatuses os ON os.OrderStatusID = o.OrderStatusID
 INNER JOIN dbo.OrderDetails od ON od.OrderID = o.OrderID
  Where o.CustomerId = 100 order by OrderDate desc;

Tengo mi clase en el lado c # como a continuación, tengo tres tablas en el lado db también. Estoy tratando de ver si puedo usar dapper para mapear 3 tablas en un objeto Order sin tener que hacer múltiples querys de selección. Necesito las 3 mejores filas de Order Table y sus tablas secundarias cargadas. OrderDetail puede tener n filas para 1 orderId.

¿Cómo puedo seleccionar un objeto anidado con 1 búsqueda utilizando Dapper?

 class Order{
      int OrderId {get;set;}      
      decimal Total {get;set;}
      List<OrderDetail> Details {get;set;}
      OrderStatus Status {get;set;}
 }

  class OrderDetail
  {
    int OrderLineId {get;set;}
    int OrderId {get;set;}  
    string ItemDescription {get;set;}
    int Quantity {get;set;}
  }

  class OrderStatus
  {
    int OrderStatusID {get;set;}
    string OrderStatusDescription {get;set;}
  }

esto es lo que he intentado hasta ahora pero sin éxito

  sqlConnection.Open();

IEnumerable orders = sqlConnection
    .Query<Order>(
        @"select Order.*, OrderDetail.* 
          from Order join OrderDetail 
               inner join on Order.OrderId = OrderDetail.OrderId
               inner join on Order.OrderStatusID = OrderStatus.OrderId
               and Order.CustomerId = 100",
        (o, od, os) =>
            {
                o.Details = od;  //this is a List<OrderDetail>
                o.Status = os;
                return o;
            }); // 

enter image description here

Respuesta popular

Hay algunas maneras de lograr su caso, pero para mí puede hacerlo mediante el siguiente código

var sql = @"Select TOP 3 o.OrderId,
    o.Total,
    os.OrderStatusID,
    os.OrderStatusDescription,
    od.OrderLineId,
    od.Quantity,
    od.ItemDescription       
    From dbo.Orders o
INNER JOIN dbo.OrderStatuses os ON os.OrderStatusID = o.OrderStatusID
INNER JOIN dbo.OrderDetails od ON od.OrderID = o.OrderID
Where o.CustomerId = 100 order by OrderDate desc;";


sqlConnection.Open();

var lookupOrders = new Dictionary<int,Order>();
var oders = sqlConnection.Query<Order, OrderStatus, OrderDetails, Order>(sql,
               (o, os, od) => 
               {
                    Order order;
                    if(!lookupOrders.ContainsKey(o.OrderId)){
                        lookupOrders.Add(o.OrderId, o);                            
                        order = o;
                        order.Details = new List<OrderDetail>();
                    }
                    else {
                        order = lookupOrders[o.OrderId];
                    }
                    order.Details.Add(od);
                    order.Status = os;
                    return order;
               }, splitOn: "OrderId, OrderStatusID, OrderLineId"
            ).Distinct();


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué