Having in LINQ Query in Entity Framework Core

Having is used to specify an additional filtering condition on the result of a grouping data from a database using Entity Framework Core.

using EntityFrameworkCore_ConsoleApp.Models;

namespace EntityFrameworkCore_ConsoleApp
{
    public class Program
    {
        static void Main(string[] args)
        {
            using (var databaseContext = new DatabaseContext())
            {
                var groups = (from product in databaseContext.Products  
                              group product by product.CategoryId into gr
                              select new
                              {
                                  gr.Key,
                                  CountProduct = gr.Count(),
                                  SumQuantities = gr.Sum(productOfGroup => productOfGroup.Price),
                                  MinPrice = gr.Min(productOfGroup => productOfGroup.Price),
                                  MaxPrice = gr.Max(productOfGroup => productOfGroup.Price),
                                  AvgPrice = gr.Average(productOfGroup => productOfGroup.Price)
                              }).Where(group => group.SumQuantities > 41).ToList();
                groups.ForEach(group =>
                {
                    Console.WriteLine("Category Id: " + group.Key);
                    Console.WriteLine("Count Product: " + group.CountProduct);
                    Console.WriteLine("Sum Quantities: " + group.SumQuantities);
                    Console.WriteLine("Min Price: " + group.MinPrice);
                    Console.WriteLine("Max Price: " + group.MaxPrice);
                    Console.WriteLine("Avg Price: " + group.AvgPrice);
                    Console.WriteLine("---------------------");
                });
            }
        }
    }
}
Category Id: 3
Count Product: 3
Sum Quantities: 79
Min Price: 17
Max Price: 43
Avg Price: 26.333333333333332
---------------------

You can use combination of Having and Skip as below:

using EntityFrameworkCore_ConsoleApp.Models;

namespace EntityFrameworkCore_ConsoleApp
{
    public class Program
    {
        static void Main(string[] args)
        {
            using (var databaseContext = new DatabaseContext())
            {
                var groups = (from product in databaseContext.Products  
                              group product by product.CategoryId into gr
                              select new
                              {
                                  gr.Key,
                                  CountProduct = gr.Count(),
                                  SumQuantities = gr.Sum(productOfGroup => productOfGroup.Price),
                                  MinPrice = gr.Min(productOfGroup => productOfGroup.Price),
                                  MaxPrice = gr.Max(productOfGroup => productOfGroup.Price),
                                  AvgPrice = gr.Average(productOfGroup => productOfGroup.Price)
                              }).Where(group => group.SumQuantities > 41).Skip(1).ToList();
                groups.ForEach(group =>
                {
                    Console.WriteLine("Category Id: " + group.Key);
                    Console.WriteLine("Count Product: " + group.CountProduct);
                    Console.WriteLine("Sum Quantities: " + group.SumQuantities);
                    Console.WriteLine("Min Price: " + group.MinPrice);
                    Console.WriteLine("Max Price: " + group.MaxPrice);
                    Console.WriteLine("Avg Price: " + group.AvgPrice);
                    Console.WriteLine("---------------------");
                });
            }
        }
    }
}
Category Id: 3
Count Product: 3
Sum Quantities: 63
Min Price: 17
Max Price: 43
Avg Price: 26.333333333333332
---------------------

You can use combination of Having and Skip and Take as below:

using EntityFrameworkCore_ConsoleApp.Models;

namespace EntityFrameworkCore_ConsoleApp
{
    public class Program
    {
        static void Main(string[] args)
        {
            using (var databaseContext = new DatabaseContext())
            {
                var groups = (from product in databaseContext.Products  
                              group product by product.CategoryId into gr
                              select new
                              {
                                  gr.Key,
                                  CountProduct = gr.Count(),
                                  SumQuantities = gr.Sum(productOfGroup => productOfGroup.Price),
                                  MinPrice = gr.Min(productOfGroup => productOfGroup.Price),
                                  MaxPrice = gr.Max(productOfGroup => productOfGroup.Price),
                                  AvgPrice = gr.Average(productOfGroup => productOfGroup.Price)
                              }).Where(group => group.SumQuantities > 41).Skip(0).Take(2).ToList();
                groups.ForEach(group =>
                {
                    Console.WriteLine("Category Id: " + group.Key);
                    Console.WriteLine("Count Product: " + group.CountProduct);
                    Console.WriteLine("Sum Quantities: " + group.SumQuantities);
                    Console.WriteLine("Min Price: " + group.MinPrice);
                    Console.WriteLine("Max Price: " + group.MaxPrice);
                    Console.WriteLine("Avg Price: " + group.AvgPrice);
                    Console.WriteLine("---------------------");
                });
            }
        }
    }
}
Category Id: 3
Count Product: 3
Sum Quantities: 79
Min Price: 17
Max Price: 43
Avg Price: 26.333333333333332
---------------------

You can use combination of Having and Skip and Take and OrderBy as below:

using EntityFrameworkCore_ConsoleApp.Models;

namespace EntityFrameworkCore_ConsoleApp
{
    public class Program
    {
        static void Main(string[] args)
        {
            using (var databaseContext = new DatabaseContext())
            {
                var groups = (from product in databaseContext.Products  
                              group product by product.CategoryId into gr
                              select new
                              {
                                  gr.Key,
                                  CountProduct = gr.Count(),
                                  SumQuantities = gr.Sum(productOfGroup => productOfGroup.Price),
                                  MinPrice = gr.Min(productOfGroup => productOfGroup.Price),
                                  MaxPrice = gr.Max(productOfGroup => productOfGroup.Price),
                                  AvgPrice = gr.Average(productOfGroup => productOfGroup.Price)
                              }).Where(group => group.SumQuantities > 41).Skip(0).Take(2).OrderByDescending(group => group.SumQuantities).ToList();
                groups.ForEach(group =>
                {
                    Console.WriteLine("Category Id: " + group.Key);
                    Console.WriteLine("Count Product: " + group.CountProduct);
                    Console.WriteLine("Sum Quantities: " + group.SumQuantities);
                    Console.WriteLine("Min Price: " + group.MinPrice);
                    Console.WriteLine("Max Price: " + group.MaxPrice);
                    Console.WriteLine("Avg Price: " + group.AvgPrice);
                    Console.WriteLine("---------------------");
                });
            }
        }
    }
}
Category Id: 3
Count Product: 3
Sum Quantities: 79
Min Price: 17
Max Price: 43
Avg Price: 26.333333333333332
---------------------