If you've been using Entity Framework Core for a while, you've probably written a query like this: var ids = new[] { 1, 2, 3, 4, 5 }; var blogs = await context.Blogs .Where(b => ids.Contains(b.Id)) .ToListAsync(); Simple enough. But under the hood, how EF Core translates that ids collection into SQL has quietly changed(again) in EF Core 10, and this time the change is significant enough to be listed as a breaking change. Let's dig into what's happening, why the EF team made this call, and what it means for your applications. A brief history To understand EF Core 10's approach, it helps to know where things stood before. EF Core 8: The OPENJSON era In EF Core 8, when you passed a collection to a LINQ Contains or Where clause, EF encoded the entire collection as a JSON string and sent it as a single parameter. SQL Server would then unpack it using the OPENJSON function: SELECT [b].[Id], [b].[Name] FROM [Blogs] AS [b] WHERE [b].[Id] IN ( ...
A colleague told me a story recently. A new architect joined his project. Experienced, credentialed, confident. And from day one, all he did was explain what was wrong with the existing system. The choices that were made, the patterns that were used, the technical debt that had accumulated. An endless inventory of flaws. I've seen this before. And it always makes me uneasy. Not because criticism is bad. Codebases do accumulate real problems. Patterns do become outdated. But there's a specific kind of criticism — reflexive, premature, delivered without curiosity — that reveals something troubling about the person offering it. The most dangerous person in a technical team isn't the one who doesn't know enough — it's the one who arrives certain they know better. Every system is a set of scars Software systems carry history inside them. A module that looks over-engineered almost certainly went through a painful incident that demanded it. A seemingly arbitra...