分组而在LINQ的preserving订购而在、LINQ、preserving

2023-09-05 00:07:08 作者:一踏万里相逢

我有一个 IQueryable的(就业)在哪里工作了,除其他事项:

I've got an IQueryable(Of Job) where Job has, amongst other things:

Property CreatedOn as DateTime
Property JobType as JobTypes

Enum JobTypes
    JobType1
    JobType2
    JobType3
End Enum

我想摆脱它是一个列表,责令 CreatedOn ,然后通过 JobType 组合在一起,计数

What I want to get out of it is a list, ordered by CreatedOn, then Grouped by JobType with a count

例如说我有(略日期)

11:00  JobType1
11:01  JobType2
11:02  JobType2
11:03  JobType2
11:04  JobType2
11:05  JobType3
11:06  JobType1
11:07  JobType1

我想

JobType1 1
JobType2 4
JobType3 1
JobType1 2

我不知道如何采取分组订货时考虑。有人可以在正确的方式来做到这一点我吗?通过preference,我想preFER流利的语法。 VB.Net或C#的罚款。

I don't know how to take ordering into account when grouping. can someone point me at the right way to do this? By preference, I'd prefer fluent Syntax. VB.Net or C# is fine.

推荐答案

这招是相当容易训练LinqToObjects做:

This trick is fairly easy to train LinqToObjects to do:

public static IEnumerable<IGrouping<TKey, TSource>> GroupContiguous<TKey, TSource>(
  this IEnumerable<TSource> source,
  Func<TSource, TKey> keySelector)
{
  bool firstIteration = true;
  MyCustomGroupImplementation<TKey, TSource> currentGroup = null;

  foreach (TSource item in source)
  {
    TKey key = keySelector(item);
    if (firstIteration)
    {
      currentGroup = new MyCustomGroupImplementation<TKey, TSource>();
      currentGroup.Key = key;
      firstIteration = false;
    }
    else if (!key.Equals(currentGroup.Key))
    {
      yield return currentGroup;
      currentGroup = new MyCustomGroupImplementation<TKey, TSource>();
      currentGroup.Key = key;
    }
    currentGroup.Add(item);
  }
  if (currentGroup != null)
  {
    yield return currentGroup;
  }
}

public class MyCustomGroupImplementation<TKey, TSource> : IGrouping<TKey, TSource>
{
  //TODO implement IGrouping and Add
}

用于通过

IEnumerable<IGrouping<JobType, Job> query = Jobs
  .OrderBy(j => j.CreatedOn)
  .GroupContiguous(j => j.JobType);

这不是那么容易的事了看previous行与任何旧的LINQ提供程序。我希望你没有教LinqToSql或LinqToEntities如何做到这一点。

It's not so easy to do a "look at the previous row" with just any old linq provider. I hope you don't have to teach LinqToSql or LinqToEntities how to do this.