Dapper map multiple join Sql Query

Dapper map multiple join Sql Query

Ho fatto del mio meglio e l'ho risolto.

Ecco la soluzione più facile e precisa secondo 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();

Non so cos'è la classe "OrderDetail", non la fornisci, quindi ho usato la classe Order.
Questo può essere fatto anche da QueryMultiple ma poiché la tua domanda include INNER JOIN non la uso.

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

Ho deciso di utilizzare Dapper per ottenere un big data per il calcolo di qualcosa. Questo è il mio metodo di estensione dapper per unire 3 tabelle nel file _RepositoryBase.cs.

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

Quindi, questa funzione ti aiuterà a ottenere dati uniti a sql tramite 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 [email protected] ";

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

Riepilogo:Scrivi la tua selezione e inserisci la divisione tra le tabelle. Dì divisioni a Dapper e ottieni i tuoi dati. L'ho usato e ho funzionato meglio di Entity Framework.