Преобразовать словарь в список - PullRequest
2 голосов
/ 26 июня 2011

У меня есть список, сгенерированный из длинного запроса, который используется для передачи отчета.

var result =  
  from..
  where..
  select new  { sale.Id, Username  = u.Name, Amount = p.amount};
output  = result.Tolist();

Однако я бы хотел избавиться от этого длинного запроса, создав вместо этого свой собственный список значений. Поэтому я создаю словарь для хранения ключа и значения. Моя цель - преобразовать словарь обратно в список, который имеет такой же вывод, как и запрос выше, чтобы его можно было добавить в мой отчет

 public static object GetSalesDataBySaleOrderID(SaleOrder sale)
    {
        List<KeyValuePair<string, object>> list = new List<KeyValuePair<string, object>>();

        for (int i = 0; i < sale.saleOrderItem.Count(); i++)
        {             
            Dictionary<string, object> result = new Dictionary<string, object>()
            {
               {sale.Id.ToString(), sale.Id},                
               {"UserName", sale.User.GetSingleUserById(sale.saleOrderItem[i].UserId).Name},
               {"Amount", sale.saleOrderItem[i].Amount},                   
            };

            list.Add(result);
        }

        return list;
    }

Я получил ошибку в list.Add(result);

Ошибка 5 Аргумент '1': невозможно преобразовать из 'System.Collections.Generic.Dictionary' в 'System.Collections.Generic.KeyValuePair'

--- EDIT ------------
Я изменил на List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();, и это решило мою ошибку.

Однако я все еще получаю значение в формате словаря enter image description here

Это должен быть предполагаемый формат вывода в списке enter image description here

Ответы [ 5 ]

4 голосов
/ 26 июня 2011

Редактировать: Изменен ответ, теперь, когда исходная ошибка ОП устранена.

 public static object GetSalesDataBySaleOrderID(SaleOrder sale)
 {
     List<KeyValuePair<string, object>> list = new List<KeyValuePair<string, object>>();
     for (int i = 0; i < sale.saleOrderItem.Count(); i++)
     {
         Dictionary<string, object> result = new Dictionary<string, object>()
         {
            {"SaleId", sale.Id},
            {"UserName", sale.User.GetSingleUserById(sale.saleOrderItem[i].UserId).Name},
            {"Amount", sale.saleOrderItem[i].Amount},
         };
         list.Add(result);
     }
     return list.Select (d => new { Id=(int)d["SaleId"], Username  = d["UserName"], Amount = (Decimal) d["Amount"]});
 } 

Действительно, вам, вероятно, следует провести рефакторинг этого метода, который вы пытаетесь заменить / кэшировать, чтобы он возвращал известный объект (не анонимный тип). Может вернуть List<Sale> или что-то еще.

1 голос
/ 26 июня 2011

Я не совсем уверен, чего вы пытаетесь добиться, чтобы перевести все это в список пар ключ-значение, когда вы на самом деле хотите вернуть список объектов.Ваша функция, как указано, может быть уменьшена до:

public static object GetSalesDataBySaleOrderID(SaleOrder sale)
{
    return sale.saleOrderItem
               .Where(s => s != null)
               .Select(s => new { 
                                  Id = s.Id,
                                  Username = sale.User.GetSingleUserById(s.UserId).Name,
                                  Amount = s.Amount 
                                })
               .ToList();
}
1 голос
/ 26 июня 2011

Составьте список из ExpandoObject. Вы можете использовать их аналогичным образом, как и анонимные объекты, за исключением того, что они изменяемы или вы можете использовать их как словарь (интерфейс).

var result = myDataContext.MyTable
    .Where(sale => /* my conditions */)
    .AsEnumerable() // use LINQ to objects at this point
    .Select(sale =>
    {
        dynamic exo = new ExpandoObject();
        exo.SaleId = sale.Id;
        exo.UserName = sale.User.GetSingleUserById(sale.saleOrderItem[i].UserId).Name;
        exo.Amount = sale.saleOrderItem[i].Amount;
        return exo as IDictionary<string, object>;
    });

IDictionary<string, object> first = result.First();
// access the properties as if it were a dictionary
int saleId = (int)first["SaleId"]; // get (and cast) the SaleId property
first["UserName"] = "Bob"; // set the UserName property

// cast it back to dynamic to access the properties as if it were an anonymous object
dynamic dfirst = first;
decimal amount = dfirst.Amount; // get the Amount property (no cast necessary)
dfirst.Amount = 3238132.12M // set the Amount property
1 голос
/ 26 июня 2011

Как насчет:

var list = new List<SalesOrder>(dictionary.Values);

или, если у вас уже есть список, созданный:

list.AddRange(dictionary.Values);
1 голос
/ 26 июня 2011

@ agent-j прав, вы должны хранить каждый словарь;однако, если вы хотите получить список пар ключ-значение, вы можете использовать:

list.AddRange(dicionary.ToList());

, который преобразует словарь в форму List<KeyValuePair<string, object>>.Это будет дублировать имя пользователя и количество ключей много раз.Я думаю, что словарный подход - это то, что вы хотите, просто выбросив его на всякий случай.

HTH.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...