2011-06-26 193 views
2

我在这里生成了一个列表,这个列表是由一个长查询生成的,该查询将数据用于抽取报表。将字典转换为列表

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'

---编辑----------- -
我已更改为List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();并解决了我的错误。

但是我仍然在字典格式 enter image description here

所获得的价值,这应该是在列表中的预期输出格式 enter image description here

+0

我改变了我的答案。让我知道它是否符合您的需求。 –

+0

你的要求看起来很奇怪,我不确定我明白你的目标是什么。你想把你的结果对象,并将它们转换为从属性名称映射到值的字典?有更有效的方法来获得这种理想的行为。实际上,使用[ExpandoObject](http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx)可以免费为您提供这一切,如果这是您想要的。 –

回答

1

我不太清楚你正在努力实现整个事情转换成键值对列表,当你真正想要的对象列表后面是什么。您的功能可以降至:

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(); 
} 
+0

工程很棒。你能请指教如何忽略所有的空值?我尝试了这一点。选择(..)。DefaultIfEmpty()。Tolist()但它仍然与对象空错误转换错误。 – VeecoTech

+1

@belinq:你必须在'!= null'上添加一个'Where'子句和过滤器。我更新了我的答案。 – ChrisWue

4

编辑:更改答案,现在的OP的原始错误得到解决。

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

@ agent-j是对的,你必须存储每个字典;但是,如果你想键值对的列表,而不是,您可以使用:

list.AddRange(dicionary.ToList()); 

哪个字典转换为List<KeyValuePair<string, object>>形式。这会多次复制用户名和金额密钥。我认为字典的方法是你想要的,只是把它扔在那里以防万一。

HTH。

1

什么:

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

,或者如果你已经创建了一个清单:

list.AddRange(dictionary.Values); 
1

让它的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