【问题标题】:Linq query with Groupby Select and foreach loop使用 Groupby Select 和 foreach 循环进行 Linq 查询
【发布时间】:2017-07-24 14:19:50
【问题描述】:
 List<APList> List = new List<APList>() --

List = statement.APList.Where(f => f.PeriodKey == periodkey
                                 && f.ClassKey == classkey
                                 && f.ClassKey != null)
                        .GroupBy(g => new { g.PostKey})
                        .Select(s => s.First()).ToList();

foreach (var item in List)
{
    item.ClassKey = null;
} 

--data 

periodkey(int)  postkey(int)   classkey(int?)       
101          12        10
100          12        11
101          11        10
100          11        11




--expected 

periodkey  postkey   classkey       
101          12        null
100          11        null

这是可行的,但我不想使用 foreach 循环。有没有更好的方法来优化查询并使用 Lambda 表达式将其写入单个 linq 查询中。

【问题讨论】:

  • .List().Foreach().ForEach(s=>s.ClassKey = null) 让我无法将 void 隐式转换为 system.collection.generic
  • 编辑您的问题并显示引发异常的代码和异常情况。
  • 为什么你需要 item.ClassKey = null 如果在你的 Where clouse 中有 f.ClassKey != null ?

标签: linq


【解决方案1】:

你可以简单地选择classKey为null

List = statement.APList.Where(f => f.PeriodKey == periodkey
                                 && f.ClassKey == classkey
                                 && f.ClassKey != null)
                        .GroupBy(g => new { g.PostKey})
                        .Select(s => s.First())
                        .Select(i => new APList() {
                            PeriodKey = i.PeriodKey,
                            ClassKey = null,
                            /* ... */
                        })                            
                        .ToList();

【讨论】:

  • 我没有意识到我可以做另一个选择并使用 AnonymousType 来明确设置我正在使用 foreach 循环执行的值。干杯
  • 这不是匿名类型,而是强类型。
  • 是的,但我确实需要传递除 null 之外的其他键。干杯
【解决方案2】:

您可以按句点和后键对它们进行分组

var result = statement.APList.Where(ap => ap.PeriodKey == periodkey)
                             .Where(ap => ap.ClassKey == classkey)
                             .Where(ap => ap.ClassKey != null)
                     .GroupBy(ap => new { ap.PeriodKey, ap.PostKey })
                     .Select(group => group.Key);

现在结果包含唯一 periodKeypostKey 的匿名对象。
您可以使用它们不将其与包含classKey 的已存在类混合。

或者,如果您仍想使用已存在的对象,则创建此类的新实例,并将 classKey 设置为 null

var finalResult = result.Select(group => new AP 
                                { 
                                    PeriodKey = group.PeriodKey,
                                    PostKey = group.PostKey
                                })
                        .ToList();

使用.ForEach 扩展方法不会进行优化,因为它会执行与其他Linq 扩展方法相同的foreach 循环。

【讨论】:

    【解决方案3】:

    根据 (Assigning values inside a LINQ Select?) 上的答案,foreach 循环(或 .ForEach)比使用 LINQ 更好,因为 LINQ 用于查询对象,而不是改变它们。

    如果你确实想替换循环,你可以改用

    List = statement.APList.Where(f => f.PeriodKey == periodkey
                                 && f.ClassKey == classkey
                                 && f.ClassKey != null)
                           .GroupBy(g => new { g.PostKey})
                           .Select(s => s.First())
                           .ToList();
    
    List.ForEach(i => i.ClassKey = null);
    

    .ForEach 必须位于单独的行上,因为它对 List 中的每个项目执行一个操作并返回 void,而不是项目列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-05
      • 2014-06-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多