如何使用结果映射将小巧的结果转换为字典
How to turn dapper result into a dictionary using result mapping
我想使用此处表示的 splitOn 功能:https://dapper-tutorial.net/result-multi-mapping
将结果的每个 Order 分组为一个整数 属性 "EmployeeId"。我听从了 How to map to a Dictionary object from database results using Dapper Dot Net?
的建议
但是我得到了一个 An item with the same key has already been added.
那么我怎样才能按 EmployeeId 对我的订单进行分组?
我无法修改 Order
class 并且我更喜欢使用字典而不是创建包装 Order 的 class。但是,如果没有其他方法,我愿意接受包装 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);
}
}
}
您可以创建一个信封 class(如果您愿意,也可以使用动态):
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) 键查找字典。
这能满足您的需求吗?
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);
我想使用此处表示的 splitOn 功能:https://dapper-tutorial.net/result-multi-mapping
将结果的每个 Order 分组为一个整数 属性 "EmployeeId"。我听从了 How to map to a Dictionary object from database results using Dapper Dot Net?
的建议但是我得到了一个 An item with the same key has already been added.
那么我怎样才能按 EmployeeId 对我的订单进行分组?
我无法修改 Order
class 并且我更喜欢使用字典而不是创建包装 Order 的 class。但是,如果没有其他方法,我愿意接受包装 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);
}
}
}
您可以创建一个信封 class(如果您愿意,也可以使用动态):
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) 键查找字典。
这能满足您的需求吗?
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);