【问题标题】:Dapper selecting nested objectsDapper 选择嵌套对象
【发布时间】:2016-05-02 14:43:17
【问题描述】:

我的 SQL 看起来像

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;

我在 c# 端有我的课程,如下所示,我在 db 端也有三个表。 我正在尝试查看是否可以使用 dapper 将 3 个表映射到一个对象 Order 中,而无需执行多个选择查询。 我需要订单表中的前 3 行及其加载的子表。 OrderDetail 可以有 n 行对应 1 个 orderId。

如何使用 dapper 选择具有 1 次查找的嵌套对象?

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

这是我迄今为止尝试过但没有成功的方法

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

【问题讨论】:

  • 什么情况下不成功?
  • @DavidL 我收到语法错误,说不能将 lambda 表达式转换为类型“对象”,因为它不是委托类型。
  • 这个问题不是你的重复,但它包含了你的问题的部分解决方案stackoverflow.com/questions/11042618/dapper-multi-mapping-issue,而列表点在这里解释stackoverflow.com/questions/7508322/…
  • @Steve 我确实注意到了,但是示例只有 2 个表连接,我有 3 个并且没有看到任何示例
  • 第一个链接包含三个连接表并解释如何正确准备查询,第二个示例显示如何填写您的List&lt;OrderDetail&gt;。很抱歉,但目前无法尝试将各个部分组合在一起来构建答案

标签: c# sql-server orm dapper micro-orm


【解决方案1】:

有一些方法可以实现你的情况,但对我来说,你可以通过下面的代码来做到这一点

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    • 2013-03-26
    相关资源
    最近更新 更多