Как превратить более привлекательный результат в словарь, используя отображение результатов - PullRequest
4 голосов
/ 02 мая 2020

Я хочу использовать функцию splitOn, обозначенную здесь: https://dapper-tutorial.net/result-multi-mapping

, чтобы сгруппировать каждый Орден результатов в целочисленное свойство «EmployeeId». Я следовал совету Как сопоставить объект Dictionary из результатов базы данных, используя Dapper Dot Net?

, но я получаю An item with the same key has already been added., так как я могу сгруппировать свои заказы по EmployeeID?

Я не могу изменить класс 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);              
        }
    }
}

Ответы [ 2 ]

1 голос
/ 09 мая 2020

Будет ли это соответствовать вашим потребностям?

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

Fiddle

0 голосов
/ 04 мая 2020

Вы можете создать класс конверта (или использовать Dynami c, если хотите):

public class OrderEntity
{
  public int EmployeeID {get;set;}
  public Order Order {get;set;}
}

И тогда преобразование из набора результатов в словарь, сгруппированный по идентификатору сотрудника, будет простым:

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) в словаре.

...