Dapper 一对多映射逻辑

Dapper One to Many Mapping Logic

dapper 教程给出了这个示例来帮助用户进行多映射(一对多) 虽然这有效,但我很好奇为什么他们让您将订单存储在字典中,但最后他们使用列表中的 linq.Distinct() 和 return。似乎只 return ordersDictionary.Values 会更干净,因为字典逻辑确保没有重复。

//Tutorial
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{            
    Dictionary<int,Order> orderDictionary = new Dictionary<int, Order>();
    List<Order> list = connection.Query<Order, OrderDetail, Order>(sql, (order, orderDetail) =>
    {
        if (!orderDictionary.TryGetValue(order.OrderID, out Order orderEntry))
        {
            orderEntry = order;
            orderEntry.OrderDetails = new List<OrderDetail>();
            orderDictionary.Add(orderEntry.OrderID, orderEntry);
        }
        orderEntry.OrderDetails.Add(orderDetail);
        return orderEntry;
    }, splitOn: "OrderID")
    .Distinct()
    .ToList();
    return list;
}

//my suggestion
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{            
    Dictionary<int,Order> orderDictionary = new Dictionary<int, Order>();
    //change 1 no need to store into list here
    connection.Query<Order, OrderDetail, Order>(sql, (order, orderDetail) =>
    {
        if (!orderDictionary.TryGetValue(order.OrderID, out Order orderEntry))
        {
            orderEntry = order;
            orderEntry.OrderDetails = new List<OrderDetail>();
            orderDictionary.Add(orderEntry.OrderID, orderEntry);
        }
        orderEntry.OrderDetails.Add(orderDetail);
        return orderEntry;
    }, splitOn: "OrderID"); //change 2 remove .Distinct().ToList()
    return orderDictionary.Values.ToList(); //change 3 return dictionaryValues
}

我是本教程的作者:https://dapper-tutorial.net/query#example-query-multi-mapping-one-to-many

why they have you store the orders in the dictionary

OrderDetail 行 return 行。因此,您要确保将 OrderDetail 添加到现有 Order,而不是为每个 OrderDetail 创建一个新的。该字典用于性能检查 Order 是否已经创建。

it would be cleaner to just return the ordersDictionary.Values

您将如何查询 return 字典值?

当然,如果你在像你这样的方法中,你可以这样做

var list = orderDictionary.Values;
return list;

但是如何使这个 Connection.Query return 字典值?每行 return 编辑一个订单/OrderDetail,因此该订单将 return 编辑多次。

Query 之外,您的字典解决方案效果很好,甚至是性能更好的解决方案,但是如果您想让 Query return 的不同订单列表没有使用 Distinct 或一些类似的方法,这是不可能的。

编辑:回答评论

my suggestion return orderDictionary.Values.ToList(); //change 3 return dictionaryValues

感谢您的宝贵反馈,我们一直很感激 ;)

在没有关系时使用查询 return 的教程,但使用字典 one to many 关系

会很奇怪
// no relationship
var orders = conn.Query<Order>("", ...).Distinct();

// one to many relationship
conn.Query<Order, OrderDetail>("", ...);
var orders = orderDictionary.Values.ToList();

您的解决方案以您的使用方式获得更好的性能,这一点毫无疑问。但这就是人们通常使用 Query 方法的方式:

var orders = conn.Query("", ...).Distinct();

var activeOrders = orders.Where(x => x.IsActive).ToList();
var inactiveOrders = orders.Where(x => !x.IsActive).ToList();

他们使用 Query 方法 returns.

不过,再一次,你做的方式没有错,如果你能做到就更好了。