Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Complex Types to What's New in EF8 #4476

Merged
merged 6 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 6 additions & 0 deletions .github/workflows/build-samples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ jobs:
dotnet-version: 6.0.x
include-prerelease: true

- name: Setup .NET 8.0 SDK
uses: actions/setup-dotnet@v1
with:
dotnet-version: 8.0.x
include-prerelease: true

- name: Build samples
working-directory: samples/core
run: dotnet build
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ For more perf-sensitive applications, database triggers can be defined to automa

Materialized (or indexed) views are similar to regular views, except that their data is stored on disk ("materialized"), rather than calculated every time the view is queried. Such views are conceptually similar to stored computed columns, as they cache the results of potentially expensive calculations; however, they cache an entire query's resultset instead of a single column. Materialized views can be queried just like any regular table, and since they are cached on disk, such queries execute very quickly and cheaply without havnig to constantly perform the expensive calculations of the query which defines the view.

Specific support for materialized views varies across databases. In some databases (e.g. [PostgreSQL](https://www.postgresql.org/docs/current/rules-materializedviews.html)), materialized views must be manually refreshed in order for their values to be synchronized with their underlying tables. This is typically done via a timer - in cases where some data lag is acceptable - or via a trigger or stored procedure call in specific conditions. [SQL Server Indexed Views](https://learn.microsoft.com/sql/relational-databases/views/create-indexed-views), on the other hand, are automatically updated as their underlying tables are modified; this ensures that the view always shows the latest data, at the cost of slower updates. In addition, SQL Server Index Views have various restrictions on what they support; consult the [documentation](https://learn.microsoft.com/sql/relational-databases/views/create-indexed-views) for more information.
Specific support for materialized views varies across databases. In some databases (e.g. [PostgreSQL](https://www.postgresql.org/docs/current/rules-materializedviews.html)), materialized views must be manually refreshed in order for their values to be synchronized with their underlying tables. This is typically done via a timer - in cases where some data lag is acceptable - or via a trigger or stored procedure call in specific conditions. [SQL Server Indexed Views](/sql/relational-databases/views/create-indexed-views), on the other hand, are automatically updated as their underlying tables are modified; this ensures that the view always shows the latest data, at the cost of slower updates. In addition, SQL Server Index Views have various restrictions on what they support; consult the [documentation](/sql/relational-databases/views/create-indexed-views) for more information.

EF doesn't currently provide any specific API for creating or maintaining views, materialized/indexed or otherwise; but it's perfectly fine to [create an empty migration and add the view definition via raw SQL](xref:core/managing-schemas/migrations/managing#arbitrary-changes-via-raw-sql).

Expand Down
21 changes: 10 additions & 11 deletions entity-framework/core/querying/complex-query-operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,23 +116,22 @@ ORDER BY [p].[AuthorId]

The aggregate operators EF Core supports are as follows

.NET | SQL
------------------------ | ---
Average(x => x.Property) | AVG(Property)
Count() | COUNT(*)
LongCount() | COUNT(*)
Max(x => x.Property) | MAX(Property)
Min(x => x.Property) | MIN(Property)
Sum(x => x.Property) | SUM(Property)
| .NET | SQL |
|--------------------------|---------------|
| Average(x => x.Property) | AVG(Property) |
| Count() | COUNT(*) |
| LongCount() | COUNT(*) |
| Max(x => x.Property) | MAX(Property) |
| Min(x => x.Property) | MIN(Property) |
| Sum(x => x.Property) | SUM(Property) |

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

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
var query = context.Books.GroupBy(s => s.Price);
-->
[!code-csharp[GroupByFinalOperator](../../../../samples/core/Miscellaneous/NewInEFCore7/GroupByFinalOperatorSample.cs?name=GroupByFinalOperator)]
```

```sql
SELECT [b].[Price], [b].[Id], [b].[AuthorId]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ This page documents API and behavior changes that have the potential to break ex

## Summary

| **Breaking change** | **Impact** |
|:---------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| [`Contains` in LINQ queries may stop working on older SQL Server versions | High |
| [SQL Server `date` and `time` now scaffold to .NET `DateOnly` and `TimeOnly`](#sqlserver-date-time-only) | Medium |
| [SQLite `Math` methods now translate to SQL](#sqlite-math) | Low |
| **Breaking change** | **Impact** |
|:---------------------------------------------------------------------------------------------------------|------------|
| [`Contains` in LINQ queries may stop working on older SQL Server versions | High |
| [SQL Server `date` and `time` now scaffold to .NET `DateOnly` and `TimeOnly`](#sqlserver-date-time-only) | Medium |
| [SQLite `Math` methods now translate to SQL](#sqlite-math) | Low |

## High-impact changes

Expand All @@ -34,7 +34,7 @@ Previously, when the `Contains` operator was used in LINQ queries with a paramet

Starting with EF Core 8.0, EF now generates SQL that is more efficient, but is unsupported on SQL Server 2014 and below.

Note that newer SQL Server versions may be configured with an older [compatibility level](https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-compatibility-level), also making them incompatible with the new SQL. This can also occur with an Azure SQL database which was migrated from a previous on-premises SQL Server instance, carrying over the old compatibility level.
Note that newer SQL Server versions may be configured with an older [compatibility level](/sql/t-sql/statements/alter-database-transact-sql-compatibility-level), also making them incompatible with the new SQL. This can also occur with an Azure SQL database which was migrated from a previous on-premises SQL Server instance, carrying over the old compatibility level.

#### Why

Expand All @@ -56,7 +56,7 @@ FROM [Blogs] AS [b]
WHERE [b].[Name] IN (N'Blog1', N'Blog2')
```

Such insertion of constant values into the SQL creates many performance problems, defeating query plan caching and causing unneeded evictions of other queries. The new EF Core 8.0 translation uses the SQL Server [`OPENJSON`](https://learn.microsoft.com/sql/t-sql/functions/openjson-transact-sql) function to instead transfer the values as a JSON array. This solves the performance issues inherent in the previous technique; however, the `OPENJSON` function is unavailable in SQL Server 2014 and below.
Such insertion of constant values into the SQL creates many performance problems, defeating query plan caching and causing unneeded evictions of other queries. The new EF Core 8.0 translation uses the SQL Server [`OPENJSON`](/sql/t-sql/functions/openjson-transact-sql) function to instead transfer the values as a JSON array. This solves the performance issues inherent in the previous technique; however, the `OPENJSON` function is unavailable in SQL Server 2014 and below.

For more information about this change, [see this blog post](https://devblogs.microsoft.com/dotnet/announcing-ef8-preview-4/).

Expand All @@ -68,7 +68,7 @@ If your database is SQL Server 2016 (13.x) or newer, or if you're using Azure SQ
SELECT name, compatibility_level FROM sys.databases;
```

If the compatibility level is below 130 (SQL Server 2016), consider modifying it to a newer value ([documentation]( https://learn.microsoft.com/sql/t-sql/statements/alter-database-transact-sql-compatibility-level#best-practices-for-upgrading-database-compatibility-leve).
If the compatibility level is below 130 (SQL Server 2016), consider modifying it to a newer value ([documentation](/sql/t-sql/statements/alter-database-transact-sql-compatibility-level#best-practices-for-upgrading-database-compatibility-leve).

Otherwise, if your database version really is older than SQL Server 2016, or is set to an old compatibility level which you cannot change for some reason, configure EF Core to revert to the older, less efficient SQL as follows:

Expand Down
Loading
Loading