Skip to content

Commit e3a119b

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 055aa73 commit e3a119b

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
@@ -22,6 +22,7 @@ This page documents API and behavior changes that have the potential to break ex
2222
| [EF Core now throws by default when no migrations are found](#migrations-not-found) | Low |
2323
| [`EFOptimizeContext` MSBuild property has been removed](#ef-optimize-context-removed) | Low |
2424
| [EF tools packages no longer reference Microsoft.EntityFrameworkCore.Design](#ef-tools-no-design-dep) | Low |
25+
| [SqlVector properties are no longer loaded by default](#sqlvector-not-auto-loaded) | Low |
2526

2627
## Medium-impact changes
2728

@@ -141,3 +142,36 @@ If your project relies on `Microsoft.EntityFrameworkCore.Design` being brought i
141142
```xml
142143
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="11.0.0" PrivateAssets="all" />
143144
```
145+
146+
<a name="sqlvector-not-auto-loaded"></a>
147+
148+
### SqlVector properties are no longer loaded by default
149+
150+
[Tracking Issue #37279](https://github.com/dotnet/efcore/issues/37279)
151+
152+
#### Old behavior
153+
154+
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.
155+
156+
#### New behavior
157+
158+
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.
159+
160+
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.
161+
162+
#### Why
163+
164+
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.
165+
166+
#### Mitigations
167+
168+
> [!NOTE]
169+
> A mechanism for opting vector properties back into automatic loading will be introduced later in the EF Core 11 release.
170+
171+
If you need to read back vector values, use an explicit projection:
172+
173+
```csharp
174+
var embeddings = await context.Blogs
175+
.Select(b => new { b.Id, b.Embedding })
176+
.ToListAsync();
177+
```

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
@@ -364,7 +364,7 @@ Once you have a vector index, you can use the `VectorSearch()` extension method
364364

365365
```csharp
366366
var blogs = await context.Blogs
367-
.VectorSearch(b => b.Embedding, "cosine", embedding, topN: 5)
367+
.VectorSearch(b => b.Embedding, embedding, "cosine", topN: 5)
368368
.ToListAsync();
369369
```
370370

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

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

377+
<a name="sqlserver-vector-not-auto-loaded"></a>
378+
379+
### Vector properties not loaded by default
380+
381+
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.
382+
383+
```csharp
384+
// Vector column is excluded from the projected entity
385+
var blogs = await context.Blogs.OrderBy(b => b.Name).ToListAsync();
386+
// Generates: SELECT [b].[Id], [b].[Name] FROM [Blogs] AS [b] ...
387+
388+
// Explicit projection still loads the vector
389+
var embeddings = await context.Blogs
390+
.Select(b => new { b.Id, b.Embedding })
391+
.ToListAsync();
392+
```
393+
394+
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.
395+
377396
<a name="sqlserver-full-text"></a>
378397

379398
### Full-text search improvements
@@ -401,6 +420,8 @@ CREATE FULLTEXT INDEX ON [Blogs]([FullName]) KEY INDEX [PK_Blogs] ON [ftCatalog]
401420

402421
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).
403422

423+
<a name="sqlserver-full-text-tvf"></a>
424+
404425
#### Full-text search table-valued functions
405426

406427
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)