EF Core 11 Vector Search: Kill Your Separate Vector Database
The current AI/RAG stack for .NET developers is architecturally absurd. You've got SQL Server holding your domain data, Pinecone or Qdrant sitting in a separate cloud for vectors, a sync pipeline duct-taped between them to keep embeddings consistent, and a completely different SDK with its own query language to search it all. Two databases. Two mental models. Eventual consistency headaches that wake you up at 3 AM.
That era just ended. EF Core 11 (Preview 5, shipped June 9, 2026) paired with SQL Server 2025 collapses this entire circus into one database, one ORM, and one query language you already know: LINQ.
I've spent 15+ years building systems on SQL Server and EF Core. The moment I saw native vector search land in a familiar DbContext, I knew this was the kind of drastic simplification I live for. Let me walk you through exactly what shipped and why most .NET teams can delete an entire infrastructure component from their architecture.
The New Primitives
Three things landed that make this work end-to-end.
The Vector Type
EF Core 11 introduces SqlVector<float>, a vector property type that maps directly to SQL Server 2025's native vector column type. You declare it on your entity like any other property:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Category { get; set; }
public bool InStock { get; set; }
[Column(TypeName = "vector(1536)")]
public SqlVector<float> Embedding { get; set; }
}
The 1536 matches OpenAI's text-embedding-3-small dimensions. Swap it for 768 or 3072 depending on your embedding model. That's the only configuration you need.
DiskANN Indexes via Fluent API
You create a DiskANN index (Microsoft's high-performance approximate nearest neighbor index) through the model builder, just like you'd configure any other index:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>()
.HasVectorIndex(b => b.Embedding, "cosine");
}
Three distance metrics are supported: cosine, euclidean, and dot. Pick cosine for normalised embeddings (most common with OpenAI/Azure OpenAI models), euclidean for spatial data, dot product when embeddings are already normalised and you want raw speed.
The killer detail: this generates a standard EF Core migration. Your vector indexes are version-controlled alongside your schema. dotnet ef migrations add AddProductEmbeddingIndex. Done.
Vectors Excluded from SELECT by Default
The EF Core team made a sharp design call here. Vector properties are excluded from SELECT by default. A 1536-dimension float vector is ~6KB per row. Loading that into every ToList() call would tank performance.
You only pull vectors when you explicitly need them. For search operations, the index handles similarity computation server-side. The raw vectors never cross the wire during normal queries.
Querying: LINQ All the Way Down
No new query language. No Pinecone client. No gRPC calls to Qdrant. Just LINQ.
Approximate Nearest Neighbor (The Fast Path)
The VectorSearch() extension method performs ANN search using your DiskANN index. This is what you'll use in production for sub-millisecond search over millions of vectors:
float[] queryEmbedding = await embeddingGenerator.GenerateVectorAsync("wireless headphones");
var results = await context.Products
.VectorSearch(p => p.Embedding, "cosine", queryEmbedding, topN: 10)
.Select(r => new { r.Value.Name, r.Value.Category, r.Distance })
.ToListAsync();
The result gives you both the entity (r.Value) and the computed distance (r.Distance). Lower distance = more similar.
Exact Search (When Precision Matters)
For smaller datasets or when you need exact results (not approximate), use EF.Functions.VectorDistance() directly in an OrderBy:
var sqlVector = new SqlVector<float>(queryEmbedding);
var results = await context.Products
.OrderBy(p => EF.Functions.VectorDistance("cosine", p.Embedding, sqlVector))
.Take(5)
.ToListAsync();
This does a brute-force scan. Fine for tables under ~100K rows. Beyond that, stick with the DiskANN index path.
Hybrid Search (The Killer Feature)
Here's what separates this from every dedicated vector database I've used. You can combine vector similarity with regular LINQ predicates in a single query:
var results = await context.Products
.Where(p => p.InStock && p.Category == "Electronics")
.VectorSearch(p => p.Embedding, "cosine", queryEmbedding, topN: 5)
.Select(r => new { r.Value.Name, r.Distance })
.ToListAsync();
Filter first, then vector search within the filtered set. Or vector search first, then filter. The SQL Server query optimiser handles the execution plan.
In Pinecone, you'd need metadata filtering with a completely different syntax. In Qdrant, you'd use their filter DSL. Here? It's just .Where(). Every .NET developer already knows this.
Full RAG Without Leaving .NET
Here's the complete Retrieval-Augmented Generation pipeline using nothing but Microsoft.Extensions.AI and EF Core. No external vector database. No sync service. No separate SDK.
// 1. Generate embedding for user question
var questionEmbedding = await embeddingGenerator.GenerateVectorAsync(userQuestion);
// 2. Find relevant documents via vector search
var relevantDocs = await context.Documents
.VectorSearch(d => d.Embedding, "cosine", questionEmbedding, topN: 3)
.Select(r => r.Value.Content)
.ToListAsync();
// 3. Build context and call LLM
var ragContext = string.Join("\n\n", relevantDocs);
var answer = await chatClient.GetResponseAsync(
$"Answer based on this context:\n{ragContext}\n\nQuestion: {userQuestion}");
Three steps. One database. One ORM. No infrastructure to sync, no eventual consistency to debug, no separate deployment to monitor.
Before and After
Before EF Core 11:
- SQL Server (domain data)
- Pinecone/Qdrant/Weaviate (vector storage)
- Background sync service (keep embeddings in sync with source data)
- Two SDKs, two connection strings, two monitoring dashboards
- Eventual consistency between domain data and vectors
After EF Core 11:
- SQL Server 2025 (everything)
- EF Core (everything)
- Embeddings live on the same row as your domain data, always consistent
- One connection string, one migration history, one backup strategy
That's not a 10% improvement. That's removing an entire layer from your architecture.
Migration and Practical Gotchas
Adding Vectors to Existing Tables
The migration is straightforward. Add the SqlVector<float> property, run dotnet ef migrations add, apply it. The column gets added as nullable by default, so existing rows will have NULL embeddings until you backfill them.
Backfilling is the real work. You'll need to iterate through existing rows, generate embeddings via your model of choice, and update them in batches. One-time data migration, not an ongoing burden.
Index Creation Time
DiskANN index creation on large tables isn't instant. Expect minutes to tens of minutes on tables with millions of rows. Plan this for a maintenance window.
Preview Status
I'll be upfront: EF Core 11 is in preview as of June 2026. The vector search APIs may shift before the November GA release. I wouldn't put this in front of paying customers today without accepting that risk. But for new projects, greenfield features, or internal tools? Start building on it now. The fundamentals (SQL Server 2025's vector support and DiskANN) are already GA on the database side.
When You Still Need a Dedicated Vector DB
If you're operating at extreme scale (billions of vectors, multi-tenant workloads across geographic regions, or you need sub-10ms p99 latency across massive datasets) dedicated vector databases still have their place. Pinecone and Qdrant have spent years optimising for exactly those scenarios.
But let's be real: most .NET teams aren't at that scale. If your vector count is in the millions or even tens of millions, SQL Server 2025 with DiskANN will handle it fine.
The 75% Easier Verdict
Here's what you're eliminating by adopting EF Core 11's vector search:
- No new infrastructure to provision, monitor, or pay for
- No sync pipeline to keep vectors consistent with source data
- No new query language. It's LINQ, which your team already knows
- No new SDK. It's EF Core, which is already in your
csproj - No eventual consistency. Vectors live on the same row as your data
Your RAG architecture just collapsed from five moving parts to one. Your team doesn't need to learn Pinecone's API or Qdrant's filter syntax. Your ops team doesn't need to monitor another database. Your billing doesn't have another line item.
If you can justify maintaining a separate vector database after trying this, I'd genuinely love to hear why. I suspect for 90% of .NET shops, that justification no longer exists.
EF Core 11 Preview 5 is available now via dotnet-ef tooling and NuGet. SQL Server 2025 is GA. Start with a spike: add an embedding column to one entity, create the index, and run a vector search. You'll have it working before lunch.