Skip to content
Merged
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
46 changes: 46 additions & 0 deletions entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,49 @@ var results = await context.Blogs
Both methods return `FullTextSearchResult<TEntity>`, giving you access to both the entity and the ranking value from SQL Server's full-text engine. This allows for more sophisticated result ordering and filtering based on relevance scores.

For more information, see the [full documentation on full-text search](xref:core/providers/sql-server/full-text-search).

<a name="sql-server-json-contains"></a>

### Translate Contains over primitive collections using JSON_CONTAINS

SQL Server 2025 introduced the [`JSON_CONTAINS`](/sql/t-sql/functions/json-contains-transact-sql) function, which checks whether a value exists in a JSON document. Starting with EF Core 11, when targeting SQL Server 2025, LINQ `Contains` queries over primitive (or scalar) collections stored as JSON are translated to use this function, replacing the previous, less efficient `OPENJSON`-based translation.

The following query checks whether a blog's `Tags` collection contains a specific tag:

```csharp
var blogs = await context.Blogs
.Where(b => b.Tags.Contains("ef-core"))
.ToListAsync();
```

Before EF 11 - or when targeting older SQL Server versions - this generates the following SQL:

```sql
SELECT [b].[Id], [b].[Name], [b].[Tags]
FROM [Blogs] AS [b]
WHERE N'ef-core' IN (
SELECT [t].[value]
FROM OPENJSON([b].[Tags]) WITH ([value] nvarchar(max) '$') AS [t]
)
```

With EF 11, configure EF to target SQL Server 2025 by setting the compatibility level as follows:

```csharp
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer("<CONNECTION STRING>", o => o.UseCompatibilityLevel(170));
```

At that point, EF will instead generate the following SQL:

```sql
SELECT [b].[Id], [b].[Name], [b].[Tags]
FROM [Blogs] AS [b]
WHERE JSON_CONTAINS([b].[Tags], 'ef-core') = 1
```

`JSON_CONTAINS()` can notably make use of a [JSON index](/sql/t-sql/statements/create-json-index-transact-sql), if one is defined.

> [!NOTE]
> `JSON_CONTAINS` does not support searching for null values. As a result, this translation is only applied when EF can determine that at least one side is non-nullable — either the item being searched for (e.g. a non-null constant or a non-nullable column), or the collection's elements. When this cannot be determined, EF falls back to the previous `OPENJSON`-based translation.