Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion entity-framework/core/providers/sql-server/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Function Mappings - Microsoft SQL Server Database Provider - EF Core
description: Function Mappings of the Microsoft SQL Server database provider
author: SamMonoRT
ms.date: 4/14/2026
ms.date: 08/19/2026
uid: core/providers/sql-server/functions
---
# Function Mappings of the Microsoft SQL Server Provider
Expand All @@ -11,6 +11,8 @@ This page shows which .NET members are translated into which SQL functions when

## Aggregate functions

For general information about using aggregate functions in queries, see [Aggregate functions](xref:core/querying/complex-query-operators#aggregate-functions).
Comment thread
AndriySvyryd marked this conversation as resolved.

.NET | SQL | Added in
----------------------------------------------------------------------- | -------------------------------- | --------
EF.Functions.StandardDeviationSample(group.Select(x => x.Property)) | STDEV(Property)
Expand Down
4 changes: 3 additions & 1 deletion entity-framework/core/providers/sqlite/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Function Mappings - SQLite Database Provider - EF Core
description: Function Mappings of the SQLite EF Core database provider
author: SamMonoRT
ms.date: 7/26/2023
ms.date: 08/19/2026
uid: core/providers/sqlite/functions
---
# Function Mappings of the SQLite EF Core Provider
Expand All @@ -11,6 +11,8 @@ This page shows which .NET members are translated into which SQL functions when

## Aggregate functions

For general information about using aggregate functions in queries, see [Aggregate functions](xref:core/querying/complex-query-operators#aggregate-functions).

.NET | SQL | Added in
----------------------------------------------------- | ---------------------------------- | --------
group.Average(x => x.Property) | AVG(Property)
Expand Down
41 changes: 39 additions & 2 deletions entity-framework/core/querying/complex-query-operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Complex Query Operators - EF Core
description: In-depth information on the more complex LINQ query operators when using Entity Framework Core
author: SamMonoRT
ms.date: 10/03/2019
ms.date: 08/19/2026
uid: core/querying/complex-query-operators
---
# Complex Query Operators
Expand Down Expand Up @@ -114,7 +114,9 @@ HAVING COUNT(*) > 0
ORDER BY [p].[AuthorId]
```

The aggregate operators EF Core supports are as follows
### Aggregate functions

Aggregate functions are typically used in the projection after `GroupBy`. Each aggregate produces a scalar value, so the projection can contain both the grouping key and aggregate results. The standard LINQ aggregate operators EF Core supports are as follows:

| .NET | SQL |
|--------------------------|---------------|
Expand All @@ -127,6 +129,41 @@ The aggregate operators EF Core supports are as follows

Additional aggregate operators may be supported. Check your provider docs for more function mappings.

Some aggregate functions allow their input to be composed. Depending on the provider, `Where` can filter the input, `OrderBy` can specify its ordering, and `Distinct` can remove duplicates. The following query illustrates these shapes:

```csharp
var query = context.Posts
.GroupBy(p => p.AuthorId)
.Select(g => new
{
g.Key,
Count = g.Count(),
DistinctBlogCount = g.Select(p => p.BlogId).Distinct().Count(),
OrderedTitles = string.Join(
"|",
g.OrderBy(p => p.Title).Select(p => p.Title)),
FilteredTitles = string.Join(
"|",
g.Where(p => p.Rating >= 4).Select(p => p.Title))
});
```

The supported aggregate functions and compositions vary by provider. Consult the provider's function mappings to determine which forms are translated.

Standard LINQ aggregate operators have `IQueryable` overloads and can be applied directly to an entire query. Some provider-specific aggregate functions expose only `IEnumerable` overloads and therefore can only be used within a grouping. To apply one of these functions to an entire query, group by a constant:

```csharp
var standardDeviation = context.Posts
.GroupBy(_ => 1)
.Select(g => EF.Functions.StandardDeviationSample(g.Select(p => p.Rating)))
.FirstOrDefault();
```

The constant creates a single group over the query results. If the source contains no rows, no group is created and `FirstOrDefault` returns the default value.

> [!NOTE]
> EF Core doesn't currently support mapping user-defined aggregate functions. This is tracked by [issue #27934](https://github.com/dotnet/efcore/issues/27934).

Even though there is no database structure to represent an `IGrouping`, in some cases, EF Core 7.0 and newer can create the groupings after the results are returned from the database. This is similar to how the [`Include`](xref:core/querying/related-data/eager) operator works when including related collections. The following LINQ query uses the GroupBy operator to group the results by the value of their Price property.

```csharp
Expand Down
18 changes: 17 additions & 1 deletion entity-framework/core/querying/user-defined-function-mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: User-defined function mapping - EF Core
description: Mapping user-defined functions to database functions
author: SamMonoRT
ms.date: 11/23/2020
ms.date: 08/19/2026
uid: core/querying/user-defined-function-mapping
---
# User-defined function mapping
Expand Down Expand Up @@ -64,6 +64,22 @@ FROM [Blogs] AS [b]
WHERE [dbo].[CommentedPostCountForBlog]([b].[BlogId]) > 1
```

### Mapping a method to a built-in function

EF Core considers a mapped function to be user-defined by default. Some databases distinguish built-in and user-defined functions when generating SQL. For example, SQL Server requires user-defined functions to be schema-qualified, but built-in functions aren't schema-qualified.

Use `IsBuiltIn` to map a CLR method to a built-in function:

[!code-csharp[Main](../../../samples/core/Querying/UserDefinedFunctionMapping/Model.cs#BuiltInFunctionDefinition)]

[!code-csharp[Main](../../../samples/core/Querying/UserDefinedFunctionMapping/Model.cs#BuiltInFunctionConfiguration)]

The <xref:Microsoft.EntityFrameworkCore.DbFunctionAttribute.IsBuiltIn> property provides the same configuration when using an attribute:

```csharp
[DbFunction(Name = "ISDATE", IsBuiltIn = true)]
```

## Mapping a method to a custom SQL

EF Core also allows for user-defined functions that get converted to a specific SQL. The SQL expression is provided using `HasTranslation` method during user-defined function configuration.
Expand Down
11 changes: 11 additions & 0 deletions samples/core/Querying/UserDefinedFunctionMapping/Model.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ public int ActivePostCountForBlog(int blogId)
=> throw new NotSupportedException();
#endregion

#region BuiltInFunctionDefinition
public static bool IsDate(string value)
=> throw new NotSupportedException();
#endregion

#region HasTranslationFunctionDefinition
public double PercentageDifference(double first, int second)
=> throw new NotSupportedException();
Expand Down Expand Up @@ -143,6 +148,12 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
.HasName("CommentedPostCountForBlog");
#endregion

#region BuiltInFunctionConfiguration
modelBuilder.HasDbFunction(typeof(BloggingContext).GetMethod(nameof(IsDate), [typeof(string)]))
.HasName("ISDATE")
.IsBuiltIn();
#endregion

#region HasTranslationFunctionConfiguration
// 100 * ABS(first - second) / ((first + second) / 2)
modelBuilder.HasDbFunction(
Expand Down
Loading