Entity Framework Core 2.2: Performance Improvements

EF Core 2.2 shipped alongside .NET Core 2.2, and while it’s not a revolutionary release, the performance improvements are worth talking about. Here’s what I’ve noticed in real-world usage.

Spatial Data Types

Finally! If you’ve been waiting to use geography types with EF Core, the wait is over. Install the spatial package:

dotnet add package Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite

Then use NetTopologySuite types in your entities:

using NetTopologySuite.Geometries;

public class Store
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Point Location { get; set; }
}

// Query stores within 10km
var nearbyStores = context.Stores
    .Where(s => s.Location.Distance(userLocation) < 10000)
    .OrderBy(s => s.Location.Distance(userLocation))
    .ToList();

Query Tags

This is one of those small features that makes a big difference in production. You can now tag your queries:

var orders = context.Orders
    .TagWith("GetRecentOrders - OrderService.cs line 42")
    .Where(o => o.Status == OrderStatus.Pending)
    .ToList();

The tag appears as a comment in the generated SQL. When you’re looking at slow query logs or SQL Profiler, you’ll immediately know which code path generated it.

Owned Entity Collections

2.1 introduced owned types, but you could only have one. Now you can have collections:

public class Order
{
    public int Id { get; set; }
    public List<OrderLine> Lines { get; set; }
}

[Owned]
public class OrderLine
{
    public string ProductName { get; set; }
    public int Quantity { get; set; }
    public decimal Price { get; set; }
}

// Configuration
modelBuilder.Entity<Order>()
    .OwnsMany(o => o.Lines);

This is great for DDD purists who want proper value objects without separate tables.

Performance Numbers

In my benchmarks with a typical CRUD application:

  • Query compilation: ~20% faster for complex queries
  • SaveChanges: ~10% improvement for batch inserts
  • Memory usage: Reduced allocations during tracking

These aren’t massive wins individually, but they add up in high-throughput scenarios.

Breaking Changes to Watch

A couple of things bit me during upgrades:

  • Some LINQ expressions that worked before now throw client evaluation warnings
  • Lazy loading behavior changed slightly with proxies
  • Migration snapshot format changed (regenerate if needed)

References


Discover more from C4: Container, Code, Cloud & Context

Subscribe to get the latest posts sent to your email.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.