如何使用结果映射将Dapper查询结果转换为字典

5

我想使用此处标记的 splitOn 功能: https://dapper-tutorial.net/result-multi-mapping

将结果中的每个 Order 分组到一个整数属性“EmployeeId”中。我遵循了如何使用 Dapper Dot Net 从数据库结果映射到字典对象? 中的建议。

但是我得到了一个 "已经添加了具有相同键的项" 的错误,那么我该如何通过 EmployeeId 对订单进行分组呢?

我不能修改 Order 类,并且我更喜欢使用字典来代替创建包装 Order 的类。然而,如果没有其他方法,我也可以接受包装 Order 的想法。

https://dotnetfiddle.net/hn6Sjf

public class Program
{
    public class Order
    {
        public int OrderID { get; set; }
        public int CustomerID { get; set; }
        public DateTime OrderDate  { get; set; }
        public int ShipperID  { get; set; }
    }

    public static void Main()
    {
        string sql = @"
            SELECT TOP 10
                EmployeeID,
                OrderID,
                CustomerID,
                OrderDate,
                ShipperID
            FROM Orders 
            ORDER BY OrderID;
        ";

        using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
        {           
            var rawList = connection.Query<Order>(sql);
            FiddleHelper.WriteTable(rawList);   


                var dict = connection.Query<int, List<Order>, KeyValuePair<int, List<Order>>>(sql,
                    (s, i) => new KeyValuePair<int, List<Order>>(s, i), null, null, true, "OrderID")
                    .ToDictionary(kv => kv.Key, kv => kv.Value);

            FiddleHelper.WriteTable(dict);              
        }
    }
}

或者,您是否考虑过(或者能否考虑,鉴于应用程序的任何限制),在SQL查询中使用for json,以便返回一个JSON字符串,该字符串可以轻松反序列化为您的数据结构?这绝对是更少的代码,并且可能具有同样的性能。如果需要,让我知道,我可以提供一些额外的指针。谢谢。 - square_particle
2个回答

1

这个是否符合您的需求?

var dict = connection.Query<int, Order, ValueTuple<int, Order>>(sql,
        (s, i) => ValueTuple.Create(s, i), null, null, true, "OrderID")
        .GroupBy(t => t.Item1, t => t.Item2, (k, v) => new {Key = k, List = v})
        .ToDictionary(kv => kv.Key, kv => kv.List);

小提琴


0
你可以创建一个信封类(或者如果你更喜欢动态方式,可以使用动态):
public class OrderEntity
{
  public int EmployeeID {get;set;}
  public Order Order {get;set;}
}

然后将结果集映射到按员工ID分组的字典中就很简单了:

var dict = new Dictionary<int,List<Order>>();
var r = connection.Query<OrderEntity, Order, OrderEntity>(sql,(orderEntity, order) => 
    {
        // You can skip that line if you want, the orderEntity is (probably) never used.
        orderEntity.Order = order;

        if(dict.ContainsKey(orderEntity.EmployeeID))
        {
            dict[orderEntity.EmployeeID].Add(orderEntity.Order);
        }
        else
        {
            dict.Add(orderEntity.EmployeeID, new List<Order> {orderEntity.Order});
        }

        return orderEntity;
    }, splitOn: "OrderID");

这种方法在结果集上只需要进行1次迭代,且只需要进行一次 O(1) 的字典键查找。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接