using Microsoft.EntityFrameworkCore;
using Microsoft.Data.SqlClient;
using System.Collections.Generic;
public static void Main()
using (var context = new BloggingContext())
context.Database.EnsureCreated();
SeedArticleEditions(context);
var topFiveArticles = new BloggingContext().Articles.Take(5).Select(x => x.Id).ToList();
var (count, latestEditionsOfArticles) = GetLatestArticleEditionsWithCount(topFiveArticles, 3);
Console.WriteLine("Found versions in total: " + count);
foreach(var articleEdition in latestEditionsOfArticles){
Console.WriteLine(JsonSerializer.Serialize(articleEdition));
private static (int, IEnumerable<ArticleEdition>) GetLatestArticleEditionsWithCount(IReadOnlyCollection<int> articleIds, int editionsToTake) {
using (var context = new BloggingContext())
var query = context.ArticleEditions.Where(articleEdition => articleIds.Contains(articleEdition.ArticleId));
.GroupBy(x => x.ArticleId)
.Select(group => group.FirstOrDefault(inner => inner.EditionNumber == group.Max(outer => outer.EditionNumber)));
return (query.Count(), query.Take(editionsToTake).ToList());
private static (int, IEnumerable<ArticleEdition>) GetLatestArticleEditionsWithClientEvaluatedCount(IReadOnlyCollection<int> articleIds, int editionsToTake) {
using (var context = new BloggingContext())
var query = context.ArticleEditions.Where(articleEdition => articleIds.Contains(articleEdition.ArticleId));
.GroupBy(x => x.ArticleId)
.Select(group => group.FirstOrDefault(inner => inner.EditionNumber == group.Max(outer => outer.EditionNumber)));
return (query.ToList().Count(), query.Take(editionsToTake).ToList());
private static void SeedArticles(BloggingContext context) {
context.Articles.AddRange(Enumerable.Range(1, 10).Select(item => new Article {Title = "Article #" + item }));
private static void SeedArticleEditions(BloggingContext context) {
var articles = context.Articles.ToList();
foreach(var article in articles){
context.ArticleEditions.AddRange(Enumerable.Range(1, 5).Select(item => new ArticleEdition {
ArticleContent = "Some very important stuff #" + item,
ModificationDate = DateTime.Now
public class BloggingContext : DbContext
public DbSet<Article> Articles { get; set; }
public DbSet<ArticleEdition> ArticleEditions { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
optionsBuilder.UseSqlServer(new SqlConnection(FiddleHelper.GetConnectionStringSqlServer()));
base.OnConfiguring(optionsBuilder);
public int Id {get; set;}
public string Title {get;set;}
public virtual ICollection<ArticleEdition> ArticleEditions {get;set;}
public class ArticleEdition {
public int ArticleId {get;set;}
public virtual Article Article {get;set;}
public int EditionNumber {get;set;}
public string ArticleContent {get;set;}
public DateTime ModificationDate {get;set;}