Skip to content

Commit eb201bd

Browse files
Copilotroji
andauthored
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 843750a commit eb201bd

File tree

3 files changed

+61
-5
lines changed

3 files changed

+61
-5
lines changed

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 (article, score) in blogs)
@@ -138,7 +141,7 @@ foreach (var (article, 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();
@@ -205,7 +208,7 @@ This query:
205208
The query produces the following SQL:
206209

207210
```sql
208-
SELECT TOP(@p3) [a0].[Id], [a0].[Content], [a0].[Embedding], [a0].[Title]
211+
SELECT TOP(@p3) [a0].[Id], [a0].[Content], [a0].[Title]
209212
FROM FREETEXTTABLE([Articles], *, @p, @p1) AS [f]
210213
LEFT JOIN VECTOR_SEARCH(
211214
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: 20 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-tvf"></a>
378397

379398
### Full-text search table-valued functions

0 commit comments

Comments
 (0)