Saa*_*adi 7 c# sql mapping orm dapper
我想将复杂对象映射到具有两个内部连接的查询的简洁结果。我知道我们有映射一个内部连接的解决方案,但我想映射两个内部连接结果。
这是场景:
我的课程是:
public class Order 
{
    public int id { get; set; }
    public string order_reference { get; set; }
    public string order_status { get; set; }
    public List<OrderLine> OrderLines { get; set; }
}
public class OrderLine
{
    public int id { get; set; }
    public int order_id { get; set; }
    public string product_number { get; set; }
    public List<OrderLineSize> OrderLineSizes { get; set; }
}
public class OrderLineSize
{
    public int id { get; set; }
    public int order_line_id { get; set; }
    public string size_name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
Order 有 OrderLines as List 和 OrderLine as OrderLineSizes as List。
现在,这是我的查询基础,我想List<Order>用正确的数据填充:
SELECT *
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
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止尝试过的:
var lookup = new Dictionary<int, Order>();
            connection.Query<Order, OrderLine, Order>(@"
                    SELECT o.*, ol.*
                    FROM orders_mstr o
                    INNER JOIN order_lines ol ON o.id = ol.order_id                    
                    ", (o, ol) => {
                    Order orderDetail;
                    if (!lookup.TryGetValue(o.id, out orderDetail))
                    {
                        lookup.Add(o.id, orderDetail = o);
                    }
                    if (orderDetail.OrderLines == null)
                        orderDetail.OrderLines = new List<OrderLine>();
                    orderDetail.OrderLines.Add(ol);
                    return orderDetail;
                }).AsQueryable();
            var resultList = lookup.Values;
Run Code Online (Sandbox Code Playgroud)
使用这个,我可以成功地用 OrderLine 映射订单对象,但我想用正确的数据填充 OrderLineSizes。
Saa*_*adi 13
我尽力了并解决了它。
根据我的说法,这是更简单和准确的解决方案。:
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();
Run Code Online (Sandbox Code Playgroud)
        小智 5
我不知道什么是“OrderDetail”类,您没有提供它,所以我使用了 Order 类。
这也可以由QueryMultiple完成,但因为您的问题包括 INNER JOIN 我不使用它。
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;
}
Run Code Online (Sandbox Code Playgroud)