Dapper map multiple joins Sql Query

前端 未结 3 861
无人及你
无人及你 2021-02-01 11:14

I want to map complex object to dapper result from query which has two inner joins. I know we\'ve solution to map one inner join but I want to map two inner joins result.

<
相关标签:
3条回答
  • 2021-02-01 11:39

    I decided to use Dapper to get a big data for calculating somethings. This is my dapper extension method to join 3 table in _RepositoryBase.cs file.

        public List<Tuple<T, T2, T3, T4>> QueryMultiple<T2, T3, T4>(string sql, object param)
            where T2 : class
            where T3 : class
        {
            using (var con = new SqlConnection(GetConnStr()))
            {
                if (con.State == ConnectionState.Closed)
                    con.Open();
    
                var query = con.Query<T, T2, T3, T4, Tuple<T, T2, T3, T4>>(sql, (t, t2, t3, t4) => Tuple.Create(t, t2, t3, t4), param);
    
                //if (query.Count() == 0)
                //    return new List<T>();
    
                var data = query.ToList();
    
                con.Close();
                con.Dispose();
    
                return data;
            }
        }
    

    Then, this function will help you to get sql joined data via dapper.

        public List<Table1> GetSqlJoinedDataViaDaper(int customerId)
        {
            var repo = new GenericRepository<T_LOOKUP>();
            var sql = @"select table1.ID Table1ID, table1.*,
                        table2.ID Table2ID, table2.*,
                        table3.ID Table3ID, table3.*
                        from dbo.Table1 table1 (nolock)
                        left outer join dbo.Table2 table2 (nolock) on table2.ID=table1.FKTable2ID
                        left outer join dbo.Table3 table3 (nolock) on table3.ID=table1.FKTable3ID
                        where table1.CustomerID=@p1 ";
    
            var resultWithJoin = repo.QueryMultiple<Table1, Table2, Table3>(sql,
                new { p1 = 1, splitOn = "Table1ID,Table2ID,Table3ID" }).ToList();
    
            var retval = new List<Table1>();
            foreach (var item in resultWithJoin)
            {
                Table1 t1 = item.Item2; //After first split
                t1.Table2 = item.Item3; //After Table2ID split
                t1.Table3 = item.Item4; //After Table3ID split
    
                retval.Add(t1);
            }
            return retval;
        }
    

    Summary: Write your select and insert split between tables. Say splits to Dapper and get your data. I used this and worked better than Entity Framework.

    0 讨论(0)
  • 2021-02-01 11:47

    I don't know what is class 'OrderDetail' you don't provide it so I used Order class.
    This can also be done by QueryMultiple but because your question includes INNER JOIN I don't use it.

    public Dictionary<int, Order> GetOrderLookup()
    {
        var lookup = new Dictionary<int, Order>();
    
        const string sql = @"   SELECT  o.id,
                                        o.order_reference,
                                        o.order_status,
    
                                        ol.id,
                                        ol.order_id,
                                        ol.product_number,
    
                                        ols.id,
                                        ols.order_line_id,
                                        ols.size_name
                                FROM    orders_mstr o
                                JOIN    order_lines ol ON o.id = ol.order_id
                                JOIN    order_line_size_relations ols ON ol.id = ols.order_line_id";
    
        List<Order> orders = null;
        using (var connection = OpenConnection(_connectionString))
        {
            orders = connection.Query<Order, OrderLine, OrderLineSize, Order>(sql, (order, orderLine, orderLizeSize) =>
            {
                orderLine.OrderLineSizes = new List<OrderLineSize> { orderLizeSize };
                order.OrderLines = new List<OrderLine>() { orderLine };
                return order;
            },
            null, commandType: CommandType.Text).ToList();
        }
    
        if (orders == null || orders.Count == 0)
        {
            return lookup;
        }
    
        foreach (var order in orders)
        {
            var contians = lookup.ContainsKey(order.id);
            if (contians)
            {
                var newLinesToAdd = new List<OrderLine>();
                var existsLines = lookup[order.id].OrderLines;
                foreach (var existsLine in existsLines)
                {
                    foreach (var newLine in order.OrderLines)
                    {
                        if (existsLine.id == newLine.id)
                        {
                            existsLine.OrderLineSizes.AddRange(newLine.OrderLineSizes);
                        }
                        else
                        {
                            newLinesToAdd.Add(newLine);
                        }
                    }
                }
                existsLines.AddRange(newLinesToAdd);
            }
            else
            {
                lookup.Add(order.id, order);
            }
        }
    
        return lookup;
    }
    
    0 讨论(0)
  • 2021-02-01 11:53

    I tried my best and solve it.

    Here is the more easy and accurate solution as per me.:

    var lookup = new Dictionary<int, OrderDetail>();
                var lookup2 = new Dictionary<int, OrderLine>();
                connection.Query<OrderDetail, OrderLine, OrderLineSize, OrderDetail>(@"
                        SELECT o.*, ol.*, ols.*
                        FROM orders_mstr o
                        INNER JOIN order_lines ol ON o.id = ol.order_id
                        INNER JOIN order_line_size_relations ols ON ol.id = ols.order_line_id           
                        ", (o, ol, ols) =>
                {
                    OrderDetail orderDetail;
                    if (!lookup.TryGetValue(o.id, out orderDetail))
                    {
                        lookup.Add(o.id, orderDetail = o);
                    }
                    OrderLine orderLine;
                    if (!lookup2.TryGetValue(ol.id, out orderLine))
                    {
                        lookup2.Add(ol.id, orderLine = ol);
                        orderDetail.OrderLines.Add(orderLine);
                    }
                    orderLine.OrderLineSizes.Add(ols);
                    return orderDetail;
                }).AsQueryable();
    
                var resultList = lookup.Values.ToList();
    
    0 讨论(0)
提交回复
热议问题