簡體   English   中英

LINQ foreach循環中的System.Linq.Enumerable + d__3a`1 [System.String]錯誤

[英]System.Linq.Enumerable+d__3a`1[System.String] error in LINQ foreach loop

我有一個列表,我試圖從另一個列表填充,我想要結合一些數據,並消除一些。

在原始列表中,數據如下所示:

 Id     Text      Description

  1      Apple     Red Delicious
  1      Apple     Green
  1      Apple     Granny 
  2      Tomato    Roma
  2      Tomato    Cherry   

我想在第二個列表中壓縮此信息,如下所示:

  Id    Text     Description
  1     Apple    Red Delicious, Green, Granny
  2     Tomato   Roma, Cherry 

我的類對象聲明如下:

 [Serializable]
 public class Food
 {
     public int Id { get;set; }
     public string Text { get;set; }
     public string Description { get;set; } 
 }

所以我想循環遍歷舊列表,這就是我在代碼中嘗試這樣做的方式:

var ids = oldList.Select(i => i.Id).Distinct(); //get distinct list of ids (e.g. 1,2)
List<Food> newList = ids.Select(i => new Food(){
   Id = i,
   Text = oldList.Where(o => o.Id == i).Select(o => o.Text).Take(1).ToString(),
   Description = string.Join(",", oldList.Where(o => o.Id == i).Select(o => o.Description).ToString())
}).ToList();

現在我因為.Take()而得到System.Linq.Enumerable + d__3a`1 [System.String]錯誤,但是如果我只改變它.ToString(),我會得到一個略有不同的錯誤但是來自同一個source System.linq.Enumerable,如果我做FirstOrDefault()同樣的東西,.Distinct()同樣的事情。

我想我明白問題是,對於Text和Description,它返回IEnumerable for Text和Description所以我沒有得到我想要的實際值,我不確定我是否理解如何正確轉換它.ToList()。 訪問這些值的正確方法是什么?

你在TakeSelect的結果上調用了ToString() - 這不會做任何好事。 目前尚不清楚為什么你在Description顯式調用ToString ,而對於Text你真的想要FirstOrDefaultFirst ,因為你只想要第一個結果:

List<Food> newList = ids.Select(i => new Food {
   Id = i,
   Text = oldList.Where(o => o.Id == i).Select(o => o.Text).FirstOrDefault(),
   Description = string.Join(",", oldList.Where(o => o.Id == i)
                                         .Select(o => o.Description))
}).ToList();

基本上,在調用ToString()上的序列( IEnumerable<T>是幾乎從未適當。

這是GroupBy運營商的典型工作:

var newList = oldList.GroupBy(x => x.Id, 
                        (key, values) => 
                           new Food() {
                             Id = key,
                             Text = values.First().Text,
                             Description = string.Join(", ", 
                                              values.Select(v => v.Description))
                            })
                     .SelectMany(x => x)
                     .ToList();

我認為你可能會使你的方法過於復雜。

這是一個非常粗略的黑客攻擊樣本(如果你願意,你可以在LinqPad中運行它),但是它使用.GroupBy來解決同樣的問題......

var l = new List<Tuple<int, string, string>>();

l.Add(Tuple.Create(1, "Apple", "Red Delicious"));
l.Add(Tuple.Create(1, "Apple", "Green"));
l.Add(Tuple.Create(1, "Apple", "Granny"));
l.Add(Tuple.Create(2, "Tomato", "Roma"));
l.Add(Tuple.Create(2, "Tomato", "Cherry"));

var res = l.GroupBy(t => t.Item2).Select(g => new { Id = g.First().Item1, Text = g.Key, Description = string.Join(", ", g.Select(i => i.Item3)) });
res.Dump(); // Linqpad output

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM