β‘ A high-performance, lightweight, provider-agnostic SQL materializer for .NET.
Hydrix is a micro-ORM built for developers who demand:
- Full control over SQL execution
- Explicit and predictable behavior
- High performance without hidden abstractions
- Efficient hierarchical entity materialization
Starting with Hydrix 3.0.0, the library is fully centered on HydrixDataCore as the single runtime entry point. The legacy Materializer stack is gone, the execution model is leaner, and the current benchmark suite places Hydrix ahead of Dapper in both flat and nested reads while allocating substantially less memory.
Hydrix is designed for performance-sensitive systems where:
- SQL must remain explicit and visible
- Developers retain full control over execution
- Behavior must be predictable and transparent
- Object graphs must be materialized efficiently from flat JOINs
Hydrix does not attempt to abstract SQL away from you.
- A LINQ provider
- An automatic SQL generator
- An entity tracking or state management framework
- A hidden abstraction over ADO.NET
- .NET Core 3.1
- .NET 6
- .NET 8
- .NET 10
HydrixDataCoreextension-first runtime model- Explicit SQL execution for text commands and stored procedures
- Strongly typed stored procedure support with
IProcedure<TDataParameter> - Entity materialization via DataAnnotations or additive Entity Framework model translation
- Entity Framework interoperability through
HydrixEntityFramework.RegisterModel(...),AddHydrixEntityFrameworkModel<TDbContext>(), andUseHydrixEntityFrameworkModels() - Nested entity support for flat JOIN projections
- Schema-aware metadata and binding caches
- Zero reflection in the materialization hot path
- Optimized scalar conversion pipeline with cached converters
- Opt-in SQL command logging
- Native SQL
INclause expansion - Fully provider-agnostic ADO.NET integration
- No non-Microsoft runtime dependencies
- Apache 2.0 licensed
MaterializerandIMaterializerwere removed from the public runtime model.HydrixDataCoreis now the only supported way to execute commands and queries.- Entity Framework interoperability arrived through
HydrixEntityFramework.RegisterModel(...), with startup/DI automation viaAddHydrixEntityFrameworkModel<TDbContext>()andUseHydrixEntityFrameworkModels(), allowing Hydrix to readOnModelCreatingmetadata and cache it alongside the existing attribute-based pipeline. ObjectExtensionsgained faster conversion paths for numeric values,DateTimeOffset,TimeSpan, and broader boolean aliases.- Converter resolution now uses cache entries keyed by
(sourceType, targetType). - Command and procedure execution hot paths now avoid per-call parameter-binding closures and use atomic hot-cache entries for stronger concurrency correctness.
HydrixOptionsgainedEnableCommandLoggingfor explicit logging control.- Row materializer execution was tightened through direct delegate invocation and
cached
MethodInfo. - Fallback type matching and schema binding were improved to reduce allocations and improve throughput in provider edge cases.
Hydrix 3.0.0 is a breaking release.
Materializerwas completely removed.IMaterializerand all Materializer-based execution/query APIs were removed.- Applications must now use the
HydrixDataCoreextension-based API surface.
If your project is already using the connection extension methods such as Execute, ExecuteScalar, Query, QueryFirst, QuerySingle, and related overloads, the migration path is straightforward.
The benchmark suite used for Hydrix 3.0.0 compares Hydrix against ADO.NET, Dapper, and Entity Framework. The release snapshot below highlights the Dapper baseline:
| Scenario | Hydrix | Dapper | Hydrix Gain |
|---|---|---|---|
| Take 1000 | 986.3 us | 1,062.0 us | 7.1% faster |
| Take 10000 | 10,362.5 us | 12,731.9 us | 18.6% faster |
| Allocation | Hydrix | Dapper | Hydrix Reduction |
|---|---|---|---|
| Take 1000 | 95.77 KB | 166.40 KB | 42.4% less |
| Take 10000 | 1039.01 KB | 1742.63 KB | 40.4% less |
| Scenario | Hydrix | Dapper | Hydrix Gain |
|---|---|---|---|
| Take 1000 | 1.684 ms | 1.744 ms | 3.4% faster |
| Take 10000 | 17.805 ms | 21.089 ms | 15.6% faster |
| Allocation | Hydrix | Dapper | Hydrix Reduction |
|---|---|---|---|
| Take 1000 | 135.24 KB | 252.84 KB | 46.5% less |
| Take 10000 | 1430.18 KB | 2602.50 KB | 45.0% less |
Hydrix 3.0.0 ships with a runtime that is not only faster than Dapper in the current suite, but also materially more memory-efficient, especially in nested materialization.
Hydrix 3.0 continues the performance work started in 2.x and tightens the runtime in a few key places:
- Metadata is built once per type and reused
- Row materializers use direct delegate invocation in hot paths
- Command and procedure parameter binding avoid per-call closure allocations
- Schema binding and matching avoid unnecessary work under contention
- Converter and binder hot caches use atomic entries for low-overhead correctness under concurrency
- Conversion fallbacks rely less on generic
Convert.ChangeType - Provider fallback type matching avoids extra boxing when metadata is incomplete
- Limit-based reads stop as early as possible
The result is lower GC pressure, more predictable latency, and stronger nested-materialization throughput.
dotnet add package Hydrixconn.Execute(
"INSERT INTO orders (id, total) VALUES (@id, @total)",
new
{
id = Guid.NewGuid(),
total = 150.75m
},
timeout: 30
);var orders = conn.Query<Order>(
"SELECT id, total FROM orders WHERE total > @min",
new { min = 100 },
timeout: 30
);var orders = conn.Query<Order>(
"SELECT * FROM orders WHERE id IN (@ids)",
new
{
ids = new[] { id1, id2, id3 }
}
);Hydrix automatically expands:
WHERE id IN (@ids_0, @ids_1, @ids_2)Each value is safely parameterized.
using Hydrix.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddHydrix(options =>
{
options.CommandTimeout = 60;
options.ParameterPrefix = "@";
options.EnableCommandLogging = true;
});Use this configuration to centralize timeout, parameter conventions, and logging behavior.
If your application already resolves DbContext instances through dependency injection, you can queue the Entity Framework model registration during service setup and apply it once during startup:
using Hydrix.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddDbContext<SalesDbContext>(options =>
options.UseSqlite("Data Source=app.db"));
services.AddHydrix();
services.AddHydrixEntityFrameworkModel<SalesDbContext>();
using var serviceProvider = services.BuildServiceProvider();
serviceProvider.UseHydrixEntityFrameworkModels();Hydrix 3.0.0 can work alongside existing Entity Framework models without
replacing the current attribute-based approach. You can register the DbContext
or its Model manually, or queue the translation through dependency injection
and execute it once during application startup.
using Hydrix.DependencyInjection;
using Hydrix.EntityFramework;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
// Manual registration
using var dbContext = new SalesDbContext(...);
HydrixEntityFramework.RegisterModel(dbContext);
HydrixEntityFramework.RegisterModel(dbContext.Model);
// Startup + DI registration
var services = new ServiceCollection();
services.AddDbContext<SalesDbContext>(options =>
options.UseSqlite("Data Source=app.db"));
services.AddHydrix();
services.AddHydrixEntityFrameworkModel<SalesDbContext>();
using var serviceProvider = services.BuildServiceProvider();
serviceProvider.UseHydrixEntityFrameworkModels();After registration, Hydrix can reuse the table names, schemas, column names,
keys, and supported reference navigations defined in OnModelCreating.
Current 3.0.0 scope:
- additive to the existing DataAnnotations-based pipeline
- only CLR types that implement
ITableare registered - reference navigations are translated for nested mappings
- collection navigations are intentionally ignored in 3.0.0
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Table("orders", Schema = "pos")]
public class Order :
DatabaseEntity, ITable
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
[Column("id")]
public Guid Id { get; set; }
[Column("total")]
public decimal Total { get; set; }
}[Table("orders", Schema = "pos")]
public class Order :
DatabaseEntity, ITable
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
[Column("id")]
public Guid Id { get; set; }
[ForeignKey("CustomerId")]
[Column("customerId")]
public Guid? CustomerId { get; set; }
[ForeignTable("customer", Schema = "pos", PrimaryKeys = new[] { "Id" }, ForeignKeys = new[] { "CustomerId" })]
public Customer Customer { get; set; }
}Hydrix only materializes nested entities when related data is present, preventing empty object creation in LEFT JOIN scenarios.
[Procedure("sp_create_order", Schema = "pos")]
public class CreateOrder :
DatabaseEntity, IProcedure<SqlParameter>
{
[Parameter("p_id", DbType.Guid)]
public Guid Id { get; set; }
[Parameter("p_total", DbType.Decimal)]
public decimal Total { get; set; }
}Command logging is opt-in and controlled through HydrixOptions.EnableCommandLogging.
Example output:
Executing DbCommand
SELECT * FROM orders WHERE id IN (@ids_0, @ids_1)
Parameters:
@ids_0 = 'a3f9...' (Guid)
@ids_1 = 'b4c1...' (Guid)
Hydrix works with any ADO.NET-compatible provider:
- SQL Server
- PostgreSQL
- MySQL
- Oracle
- DB2
- Others
Hydrix is built around the following principles:
- Explicit SQL
- Deterministic behavior
- Performance first
- No hidden abstractions
- ADO.NET as a solid foundation
Hydrix is an open-source project built and maintained with care, transparency, and a long-term vision.
If Hydrix helps you build reliable, predictable, and high-performance data access layers, consider supporting the project. Your support helps ensure ongoing maintenance, improvements, documentation, and long-term sustainability.
You can support Hydrix through GitHub Sponsors:
π https://github.com/sponsors/marcelo-mattos
Every contribution, whether financial or by sharing feedback and usage experiences, is deeply appreciated.
This project is licensed under the Apache License 2.0. See the LICENSE and NOTICE files for details.
Marcelo Matos dos Santos Software Engineer β’ Open Source Maintainer. Engineering clarity. Delivering transformation.