Skip to content

Commit 11240bc

Browse files
Copilotroji
andcommitted
Document: vector properties not loaded by default in EF Core 11 (#5286)
Document dotnet/efcore#37279 Co-authored-by: Shay Rojansky <roji@roji.org>
1 parent 002e666 commit 11240bc

3 files changed

Lines changed: 63 additions & 5 deletions

File tree

entity-framework/core/providers/sql-server/vector-search.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ await context.SaveChangesAsync();
6666

6767
Once you have embeddings saved to your database, you're ready to perform vector similarity search over them.
6868

69+
> [!NOTE]
70+
> Starting with EF Core 11, vector properties are not loaded by default when querying entities, since vectors are typically large and are rarely needed to be read back. Prior to EF Core 11, vector properties were always loaded like any other property.
71+
6972
## Exact search with VECTOR_DISTANCE()
7073

7174
The [`EF.Functions.VectorDistance()`](/sql/t-sql/functions/vector-distance-transact-sql) function computes the *exact* distance between two vectors. Use it to perform similarity search for a given user query:
@@ -126,7 +129,7 @@ Once you have a vector index, use the `VectorSearch()` extension method on your
126129

127130
```csharp
128131
var blogs = await context.Blogs
129-
.VectorSearch(b => b.Embedding, "cosine", embedding, topN: 5)
132+
.VectorSearch(b => b.Embedding, embedding, "cosine", topN: 5)
130133
.ToListAsync();
131134

132135
foreach (var (blog, score) in blogs)
@@ -138,7 +141,7 @@ foreach (var (blog, score) in blogs)
138141
This translates to the following SQL:
139142

140143
```sql
141-
SELECT [v].[Id], [v].[Embedding], [v].[Name]
144+
SELECT [v].[Id], [v].[Name], [v].[Distance]
142145
FROM VECTOR_SEARCH([Blogs], 'Embedding', @__embedding, 'metric = cosine', @__topN)
143146
```
144147

@@ -148,7 +151,7 @@ The `topN` parameter specifies the maximum number of results to return.
148151

149152
```csharp
150153
var searchResults = await context.Blogs
151-
.VectorSearch(b => b.Embedding, "cosine", embedding, topN: 5)
154+
.VectorSearch(b => b.Embedding, embedding, "cosine", topN: 5)
152155
.Where(r => r.Distance < 0.05)
153156
.Select(r => new { Blog = r.Value, Distance = r.Distance })
154157
.ToListAsync();
@@ -206,7 +209,7 @@ This query:
206209
The query produces the following SQL:
207210

208211
```sql
209-
SELECT TOP(@p3) [a0].[Id], [a0].[Content], [a0].[Embedding], [a0].[Title]
212+
SELECT TOP(@p3) [a0].[Id], [a0].[Content], [a0].[Title]
210213
FROM FREETEXTTABLE([Articles], *, @p, @p1) AS [f]
211214
LEFT JOIN VECTOR_SEARCH(
212215
TABLE = [Articles] AS [a0],

entity-framework/core/what-is-new/ef-core-11.0/breaking-changes.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ This page documents API and behavior changes that have the potential to break ex
2525
| [EF Core now throws by default when no migrations are found](#migrations-not-found) | Low |
2626
| [`EFOptimizeContext` MSBuild property has been removed](#ef-optimize-context-removed) | Low |
2727
| [EF tools packages no longer reference Microsoft.EntityFrameworkCore.Design](#ef-tools-no-design-dep) | Low |
28+
| [SqlVector properties are no longer loaded by default](#sqlvector-not-auto-loaded) | Low |
2829

2930
## Medium-impact changes
3031

@@ -145,6 +146,39 @@ If your project relies on `Microsoft.EntityFrameworkCore.Design` being brought i
145146
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="11.0.0" PrivateAssets="all" />
146147
```
147148

149+
<a name="sqlvector-not-auto-loaded"></a>
150+
151+
### SqlVector properties are no longer loaded by default
152+
153+
[Tracking Issue #37279](https://github.com/dotnet/efcore/issues/37279)
154+
155+
#### Old behavior
156+
157+
Previously, when querying entities with `SqlVector<T>` properties, EF Core included the vector column in `SELECT` statements and populated the property on the returned entity.
158+
159+
#### New behavior
160+
161+
Starting with EF Core 11.0, `SqlVector<T>` properties are no longer included in `SELECT` statements when materializing entities. The property will be `null` on returned entities.
162+
163+
Vector properties can still be used in `WHERE` and `ORDER BY` clauses—including with `VectorDistance()` and `VectorSearch()`; they just won't be included in the entity projection.
164+
165+
#### Why
166+
167+
Vector columns can be very large, containing hundreds or thousands of floating-point values. In the vast majority of cases, vectors are written to the database and then used for search, without needing to be read back. Excluding them from `SELECT` by default avoids unnecessary data transfer.
168+
169+
#### Mitigations
170+
171+
> [!NOTE]
172+
> A mechanism for opting vector properties back into automatic loading will be introduced later in the EF Core 11 release.
173+
174+
If you need to read back vector values, use an explicit projection:
175+
176+
```csharp
177+
var embeddings = await context.Blogs
178+
.Select(b => new { b.Id, b.Embedding })
179+
.ToListAsync();
180+
```
181+
148182
<a name="MDS-breaking-changes"></a>
149183

150184
## Microsoft.Data.Sqlite breaking changes

entity-framework/core/what-is-new/ef-core-11.0/whatsnew.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ Once you have a vector index, you can use the `VectorSearch()` extension method
402402

403403
```csharp
404404
var blogs = await context.Blogs
405-
.VectorSearch(b => b.Embedding, "cosine", embedding, topN: 5)
405+
.VectorSearch(b => b.Embedding, embedding, "cosine", topN: 5)
406406
.ToListAsync();
407407
```
408408

@@ -412,6 +412,25 @@ This translates to the SQL Server [`VECTOR_SEARCH()`](/sql/t-sql/functions/vecto
412412

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

415+
<a name="sqlserver-vector-not-auto-loaded"></a>
416+
417+
### Vector properties not loaded by default
418+
419+
EF Core 11 changes how vector properties are loaded: `SqlVector<T>` columns are no longer included in `SELECT` statements when materializing entities. Since vectors can be quite large—containing hundreds or thousands of floating-point numbers—this avoids unnecessary data transfer in the common case where vectors are ingested and used for search but not read back.
420+
421+
```csharp
422+
// Vector column is excluded from the projected entity
423+
var blogs = await context.Blogs.OrderBy(b => b.Name).ToListAsync();
424+
// Generates: SELECT [b].[Id], [b].[Name] FROM [Blogs] AS [b] ...
425+
426+
// Explicit projection still loads the vector
427+
var embeddings = await context.Blogs
428+
.Select(b => new { b.Id, b.Embedding })
429+
.ToListAsync();
430+
```
431+
432+
Vector properties can still be used in `WHERE` and `ORDER BY` clauses—including with `VectorDistance()` and `VectorSearch()`—and EF will correctly include them in the SQL, just not in the entity projection.
433+
415434
<a name="sqlserver-full-text"></a>
416435

417436
### Full-text search improvements
@@ -439,6 +458,8 @@ CREATE FULLTEXT INDEX ON [Blogs]([FullName]) KEY INDEX [PK_Blogs] ON [ftCatalog]
439458

440459
Previously, full-text catalog and index creation had to be managed manually by adding SQL to migrations. For full details on setting up full-text catalogs and indexes, see the [full-text search documentation](xref:core/providers/sql-server/full-text-search#setting-up-full-text-search).
441460

461+
<a name="sqlserver-full-text-tvf"></a>
462+
442463
#### Full-text search table-valued functions
443464

444465
EF Core has long provided support for SQL Server's full-text search predicates `FREETEXT()` and `CONTAINS()`, via `EF.Functions.FreeText()` and `EF.Functions.Contains()`. These predicates can be used in LINQ `Where()` clauses to filter results based on search criteria.

0 commit comments

Comments
 (0)