While working with Entity Framework SQL developers sometimes get struck on how to use group by clause with the sum, count min, and max, etc.We will use different types of an aggregate functions, and group by clause, to show the example.

Entity framework group by example

Now let’s understand with an example, that we are going to create a table, first for ProductSales includes ProductName,ProductCategory, StoreCountry, SaleAmount, and OrderDate.

ProductSales Table

Id ProductName StoreCountry SaleAmount ProductCategory OrderDate
1 TVs India 2000 Electronics 3/29/2022 13:47
2 Harry Potter USA 1500 Books 3/30/2022 13:47
3 Tanis UK 1200 Sports 4/15/2022 13:47
4 Jeans India 3000 Clothing 4/15/2022 13:47
5 Ball UK 2200 Sports 4/16/2022 13:47
6 Cap USA 800 Clothing 4/17/2022 13:47
7 Keyboard India 600 Computers 4/20/2022 13:47
8 Top USA 1400 Clothing 4/22/2022 13:47
9 Bat India 1600 Sports 5/11/2022 13:47
10 Laptop UK 900 Computers 5/12/2022 13:47
11 Refrigerators UK 700 Electronics 5/13/2022 13:47
12 Alice’s Adventures India 600 Books 5/16/2022 13:47
13 T-shirt USA 550 Clothing 5/18/2022 13:47
14 Refrigerators India 780 Electronics 5/21/2022 13:47

Entity framework Group by sum

I want to calculate the total sales amount generated by ProductCategory. We can achieve this by using the 'group by' clause. To do it manually, we would take each Electronics record and add up their sale amount, then do the same for Books records. Essentially, we first group the records by ProductCategory and then sum the saleamount column within each group, which is why we use the 'group by' clause.

So, the query groups the ProductSales collection by ProductCategory and calculates the total sales amount for each product category. The result is stored in the sales variable as an enumerable collection of anonymous objects with ProductCategory and TotalSale properties.

Sql Query:

Select ProductCategory, SUM(SaleAmount) as TotalSale  from ProductSales  Group by ProductCategory

Linq Query:

 var sales = from r in ProductSales group r by r.ProductCategory into gp select new {
   ProductCategory = gp.Key, TotalSale = gp.Sum(a => a.SaleAmount)
 };

Output:

ProductCategory SaleAmount
Books 2100
Clothing 5750
Computers 1500
Electronics 3480
Sports 5000

Entity framework group by multiple columns

Let's consider another example where we use 'group by' with multiple columns. Now, we're not only grouping by ProductCategory but also by the store's Country. For instance, we want to know the total sales generated for each product category—Electronics, Books, Clothing, Computers, and Sports—in the USA. This means we're grouping by both the ProductCategory and Country columns. Essentially, we're first grouping the total sales by country and then further by ProductCategory.

The query groups the ProductSales list by a combination of StoreCountry and ProductCategory, and calculates the total sales amount for each unique combination. The result is stored in the sales variable as an enumerable collection of anonymous objects with StoreCountry, ProductCategory, and TotalSale properties.

Sql Query:

Select StoreCountry, ProductCategory, SUM(SaleAmount) as TotalSale  from ProductSales  Group by StoreCountry, ProductCategory

Linq Query:

var sales = from r in ProductSales group r by new {
  r.StoreCountry, r.ProductCategory
}

into gp select new {
  StoreCountr = gp.Key.StoreCountry, ProductCategory = gp.Key.ProductCategory, TotalSale = gp.Sum(a => a.SaleAmount)
};


Output:

StoreCountry ProductCategory TotalSale
India Books 600
USA Books 1500
India Clothing 3000
USA Clothing 2750
India Computers 600
UK Computers 900
India Electronics 2780
UK Electronics 700
India Sports 1600
UK Sports 3400

Entity framework group by with Order BY Clause and count

Let's illustrate with an example. We're displaying the total sales by country and ProductCategory, and we also want to include the total number of orders. To find the total number of orders, we can use the Count() function. Looking at the ProductSales table, we have 14 records. Now, we'll determine the total number of orders within the ProductSales table, and we'll use the 'order by' clause along with 'group by'.

The below query groups the ProductSales list by a combination of StoreCountry and ProductCategory, calculates the total sales amount and the total number of orders for each group, and then sorts the result by the TotalSales property in ascending order. 

The result is stored in the sales variable as an enumerable collection of anonymous objects with StoreCountry, ProductCategory, TotalSales, and TotalOrder properties.

Sql Query:

Select StoreCountry, ProductCategory, SUM(SaleAmount) as TotalSales,COUNT(Id) as TotalOrder  from ProductSales  group by StoreCountry, ProductCategory  order by TotalSales

Linq Query:

var sales = (from r in ProductSales group r by new {
    r.StoreCountry, r.ProductCategory
  }
  into gp select new {
    StoreCountry = gp.Key.StoreCountry, ProductCategory = gp.Key.ProductCategory, TotalSales = gp.Sum(item => item.SaleAmount), TotalOrder = gp.Count()
  }).OrderBy(a => a.TotalSales);


Output:

StoreCountry ProductCategory TotalSales TotalOrder
India Books 600 1
India Computers 600 1
UK Electronics 700 1
UK Computers 900 1
USA Books 1500 1
India Sports 1600 1
USA Clothing 2750 3
India Electronics 2780 2
India Clothing 3000 1
UK Sports 3400 2

Entity framework group by example with where clause

Now, suppose we want to filter the output result to only include the ProductSales for the Books ProductCategory. To filter the records, we can use the 'where' clause, specifying that the ProductCategory is equal to 'Books'.

So, this query is similar to the above one, but it includes an additional filter to only consider records where the ProductCategory is "Books". The result is stored in the sales variable as an enumerable collection of anonymous objects with StoreCountry, ProductCategory, TotalSales, and TotalOrder properties, sorted by TotalSales in ascending order.

Sql Query:

Select StoreCountry, ProductCategory, SUM(SaleAmount) as TotalSales,COUNT(Id) as TotalOrder  from ProductSales  where ProductCategory='Books'  group by StoreCountry, ProductCategory

Linq Query:

var sales = (from r in ProductSales where r.ProductCategory == "Books"
  group r by new {
    r.StoreCountry, r.ProductCategory
  }
  into gp select new {
    StoreCountry = gp.Key.StoreCountry, ProductCategory = gp.Key.ProductCategory, TotalSales = gp.Sum(item => item.SaleAmount), TotalOrder = gp.Count()
  }).OrderBy(a => a.TotalSales);

Output:

StoreCountry ProductCategory TotalSales TotalOrder
India Books 600 1
USA Books 1500 1

Entity framework group by max

Lets’ say, I want the max product sales that we are generating by StoreCountry.

Sql Query:

Select ProductCategory, Max(SaleAmount) as TotalSales  from ProductSales  Group by ProductCategory

Linq Query:

 var sales = (from r in ProductSales group r by r.ProductCategory into gp select new {
   ProductCategory = gp.Key, TotalSales = gp.Max(item => item.SaleAmount),
 });

Output:

ProductCategory TotalSales
Books 1500
Clothing 3000
Computers 900
Electronics 2000
Sports 2200

Entity framework group by min

Lets’ say, I want the min product sales that we are generating by StoreCountry.

Sql Query:

Select ProductCategory, MIN(SaleAmount) as TotalSales  from ProductSales  Group by ProductCategory

Linq Query:

var sales = (from r in ProductSales group r by r.ProductCategory into gp select new {
  ProductCategory = gp.Key, TotalSales = gp.Min(item => item.SaleAmount),
});

Output:

ProductCategory TotalSales
Books 600
Clothing 550
Computers 600
Electronics 700
Sports 1200

Below is the table script which has some dummy data and you can get the SQL table script for your testing.

 

CREATE TABLE [dbo].[productsales]
             (
                          [id] [INT] IDENTITY(1,1) NOT NULL,
                          [productname] [NVARCHAR](max) NULL,
                          [storecountry] [NVARCHAR](max) NULL,
                          [saleamount] [DECIMAL](18, 2) NULL,
                          [productcategory] [NVARCHAR](max) NULL,
                          [orderdate] [DATETIME] NOT NULL,
                          CONSTRAINT [PK_ProductSales] PRIMARY KEY CLUSTERED ( [id] ASC )
             )
ON [PRIMARY] textimage_on [PRIMARY]goSET IDENTITY_INSERT [dbo].[ProductSales] ONgoINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              1,
              'TVs',
              'India',
              Cast(2000.00 AS DECIMAL(18, 2)),
              'Electronics',
              Cast('2022-03-29T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              2,
              'Harry Potter',
              'USA',
              Cast(1500.00 AS DECIMAL(18, 2)),
              'Books',
              Cast('2022-03-30T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              3,
              'Tanis',
              'UK',
              Cast(1200.00 AS DECIMAL(18, 2)),
              'Sports',
              Cast('2022-04-15T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              4,
              'Jeans',
              'India',
              Cast(3000.00 AS DECIMAL(18, 2)),
              'Clothing',
              Cast('2022-04-15T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              5,
              'Ball',
              'UK',
              Cast(2200.00 AS DECIMAL(18, 2)),
              'Sports',
              Cast('2022-04-16T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              6,
              'Cap',
              'USA',
              Cast(800.00 AS DECIMAL(18, 2)),
              'Clothing',
              Cast('2022-04-17T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              7,
              'Keyboard',
              'India',
              Cast(600.00 AS DECIMAL(18, 2)),
              'Computers',
              Cast('2022-04-20T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              8,
              'Top',
              'USA',
              Cast(1400.00 AS DECIMAL(18, 2)),
              'Clothing',
              Cast('2022-04-22T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              9,
              'Bat',
              'India',
              Cast(1600.00 AS DECIMAL(18, 2)),
              'Sports',
              Cast('2022-05-11T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              10,
              'Laptop',
              'UK',
              Cast(900.00 AS DECIMAL(18, 2)),
              'Computers',
              Cast('2022-05-12T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              11,
              'Refrigerators',
              'UK',
              Cast(700.00 AS DECIMAL(18, 2)),
              'Electronics',
              Cast('2022-05-13T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              12,
              'Alice''s Adventures',
              'India',
              Cast(600.00 AS DECIMAL(18, 2)),
              'Books',
              Cast('2022-05-16T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              13,
              'T-shirt',
              'USA',
              Cast(550.00 AS DECIMAL(18, 2)),
              'Clothing',
              Cast('2022-05-18T13:47:39.110' AS DATETIME)
       )goINSERT [dbo].[productsales]
       (
              [id],
              [productname],
              [storecountry],
              [saleamount],
              [productcategory],
              [orderdate]
       )
       VALUES
       (
              14,
              'Refrigerators',
              'India',
              Cast(780.00 AS DECIMAL(18, 2)),
              'Electronics',
              Cast('2022-05-21T13:47:39.110' AS DATETIME)
       )goSET IDENTITY_INSERT [dbo].[ProductSales] OFF

We used to open an association with the information base, make a DataSet to get or present the information to the data set, convert information from the DataSet to .NET items or the other way around to apply business rules. This was an unwieldy and mistake inclined process. Microsoft has given a system called Element Framework to robotize every one of these information base related exercises for your application.

Substance Framework is an open-source ORM system for .NET applications upheld by Microsoft. It empowers engineers to work with information utilizing objects of space explicit classes without zeroing in on the hidden data set tables and segments where this information is put away. With the Entity Framework, engineers can work at a more elevated level of deliberation when they manage information, and can make and keep up with information situated applications with less code contrasted and customary applications.

  • EF Core is a cross-stage system which can run on Windows, Linux and Mac.
  • EF (Entity Framework) makes an EDM (Entity Data Model) in view of POCO (Plain Old CLR Object) elements with get/set properties of various information types.
  • It utilizes this model while questioning or saving substance information to the fundamental data set.
  • EF permits us to utilize LINQ inquiries (C#/VB.NET) to recover information from the hidden data set. The information base supplier will make an interpretation of this LINQ questions to the data set explicit inquiry language (for example SQL for a social data set).
  • EF additionally permits us to execute crude SQL inquiries straightforwardly to the information base.
  • EF monitors changes happened to cases of your substances (Property estimations) which should be submitted to the information base.