Home > Enterprise >  C# linq return every n-th row of a list
C# linq return every n-th row of a list

Time:04-23

I'm using .NET 6, I have a class 'projectStatistics' Which contains the statistics of a project on a given day.

public class ProjectStatistics {
   public int ProjectStatisticsId {get; set;}
   public Project Project {get; set}
   public DateTime Date {get; set}
   public int statistic1 {get; set}
   public int statistic3 {get; set}
   ...
   ...
}

Since querying this result is resource intensive it is done once every 24h in the background. Then the result is stored in the database, which can then be used to create a chart.

Now the thing I'm struggling with is when there are e.g., 1000 rows in the database I don't want to make a chart with all these records, let's say I would like to make a chart with 50 dates (records in the database)

Then I would like to return all the rows in the table where row % 20 == 0, the problem is I can't use the rowId to check whether a row % x == 0. since the table contains statistics for multiple projects.

I found this question on stack overflow: Split one list into multiple lists by divisible number

I have this LINQ statement:

var result = projectStatistics
   .Where(s => s.Project == project) // Note: project is a repo method parameter
   .Select( (value, index) => new
   {
     value, 
     index
   })
   .GroupBy(item => item.index % 20, item => item.value) // Note: 20 is a repo method parameter.
   .Select(chunk => chunk.FirstOrDefault()).AsEnumerable();

Only this query gives me following error:

The LINQ expression 'DbSet<ProjectStatistics>()
    .Where(s => s.Project == __project_0)
    .Select((value, index) => new { 
        value = value, 
        index = index
     })' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.

CodePudding user response:

I think the problem LINQ to Entities might not understand how to convert that Select overload (which you are using)

We can see that from MSDN Supported and Unsupported LINQ Methods (LINQ to Entities)

Select Not supported : IQueryable Select<TSource, TResult>( this IQueryable source, Expression<Func<TSource, int, TResult>> selector )

we can use AsEnumerable() before you use the Select overload

From your logic, I do some modifications to try to let the code simple

var result = projectStatistics
   .Where(s => s.Project == project)
   .AsEnumerable()
   .Select( (value, index) => new
   {
     value, 
     grp = index % 20
   })
   .Where(s => s.grp == 0);
  • Related