SparseFields is a modular, high-performance C# library for dynamic SQL-level projections in Entity Framework Core. It satisfies JSON:API-style "Sparse Fieldsets" while ensuring your database only returns the columns you actually need.
- 🎯 SQL-Level Projection: Fetch only requested columns, significantly reducing database load and network traffic.
- 🔒 Security by Design: Mandatory whitelisting via
FieldMap<T>prevents accidental exposure of sensitive data. - 🌳 Deep Nesting & Circular Safety: Recursively projects through complex relationship trees with built-in protection against circular references.
- ⚡ Modular Design: Choose the level of integration you need (Core, EF Core, or Postgres-specific).
- 💉 DI Ready: Seamlessly integrates with
IServiceCollection.
| Package | Purpose |
|---|---|
| SparseFields.Core | Mapping engine, recursive builder, and DI configuration. |
| SparseFields.EntityFrameworkCore | Basic .Project() extensions for standard EF Core providers. |
| SparseFields.EntityFrameworkCore.Postgres | Advanced .Project() extensions with Split Query support. |
public class PostMap : FieldMap<Post>
{
public PostMap()
{
Map("id", x => x.Id);
Map("title", x => x.Title);
Map("author", x => x.Author); // Auto-detected as navigation
Map("tags", x => x.Tags); // Auto-detected as collection
}
}builder.Services.AddSparseFields(conf =>
{
conf.WithMap(new PostMap())
.WithMap(new AuthorMap());
});Simply call .Project() on your query. If using the Postgres package, you gain access to the splitQuery parameter.
using Microsoft.EntityFrameworkCore;
// using Microsoft.EntityFrameworkCore.Postgres; // For splitQuery support
[HttpGet]
public async Task<IActionResult> GetPosts([FromQuery] string[] fields)
{
return Ok(await _db.Posts
.AsNoTracking()
.Project(fields, splitQuery: true) // Optimized for deep collections
.ToListAsync());
}SparseFields tracks visited types in the current projection branch. If a circular reference is detected (e.g., Author -> Books -> Author), it stops recursion to prevent stack overflows.
In the Postgres package, the .Project() method includes a splitQuery flag. Setting this to true applies EF Core's AsSplitQuery(), preventing Cartesian product performance degradation in complex inclusions.
Distributed under the MIT License.