{"id":37031965,"url":"https://github.com/marcelo-mattos/hydrix","last_synced_at":"2026-04-09T03:01:49.769Z","repository":{"id":329627893,"uuid":"1118537505","full_name":"marcelo-mattos/hydrix","owner":"marcelo-mattos","description":"Hydrix is a minimal ORM for .NET designed for developers who prefer full control over their SQL, offering fast, predictable, and transparent object hydration.","archived":false,"fork":false,"pushed_at":"2026-04-01T09:19:04.000Z","size":7295,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-01T11:32:30.323Z","etag":null,"topics":["ado-net","hydration","hydrix","materializer","micro-orm","sql"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcelo-mattos.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"marcelo-matos"}},"created_at":"2025-12-17T22:58:57.000Z","updated_at":"2026-02-28T05:26:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/marcelo-mattos/hydrix","commit_stats":null,"previous_names":["marcelo-mattos/hydrix"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/marcelo-mattos/hydrix","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcelo-mattos%2Fhydrix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcelo-mattos%2Fhydrix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcelo-mattos%2Fhydrix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcelo-mattos%2Fhydrix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcelo-mattos","download_url":"https://codeload.github.com/marcelo-mattos/hydrix/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcelo-mattos%2Fhydrix/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31338157,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T04:42:29.251Z","status":"ssl_error","status_checked_at":"2026-04-03T04:42:12.667Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ado-net","hydration","hydrix","materializer","micro-orm","sql"],"created_at":"2026-01-14T03:56:42.711Z","updated_at":"2026-04-09T03:01:49.759Z","avatar_url":"https://github.com/marcelo-mattos.png","language":"C#","readme":"# Hydrix\n\n![NuGet](https://img.shields.io/nuget/v/Hydrix)\n![NuGet Downloads](https://img.shields.io/nuget/dt/Hydrix)\n![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=marcelo-mattos_hydrix\u0026metric=alert_status)](https://sonarcloud.io/summary/new_code?id=marcelo-mattos_hydrix)\n\n⚡ **A high-performance, lightweight, provider-agnostic SQL materializer for .NET.**\n\nHydrix is a **micro-ORM** built for developers who demand:\n\n- Full control over SQL execution\n- Explicit and predictable behavior\n- High performance without hidden abstractions\n- Efficient hierarchical entity materialization\n\nStarting 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.\n\n---\n\n## 🧭 Why Hydrix?\n\nHydrix is designed for performance-sensitive systems where:\n\n- SQL must remain explicit and visible\n- Developers retain full control over execution\n- Behavior must be predictable and transparent\n- Object graphs must be materialized efficiently from flat JOINs\n\nHydrix does not attempt to abstract SQL away from you.\n\n---\n\n## ⚠️ What Hydrix is not\n\n- A LINQ provider\n- An automatic SQL generator\n- An entity tracking or state management framework\n- A hidden abstraction over ADO.NET\n\n---\n\n## ⚙️ Supported frameworks\n\n- .NET Core 3.1\n- .NET 6\n- .NET 8\n- .NET 10\n\n---\n\n## ✨ Key Features\n\n- `HydrixDataCore` extension-first runtime model\n- Explicit SQL execution for text commands and stored procedures\n- Strongly typed stored procedure support with `IProcedure\u003cTDataParameter\u003e`\n- Entity materialization via DataAnnotations or additive Entity Framework\n  model translation\n- Entity Framework interoperability through\n  `HydrixEntityFramework.RegisterModel(...)`,\n  `AddHydrixEntityFrameworkModel\u003cTDbContext\u003e()`, and\n  `UseHydrixEntityFrameworkModels()`\n- Nested entity support for flat JOIN projections\n- Schema-aware metadata and binding caches\n- Zero reflection in the materialization hot path\n- Optimized scalar conversion pipeline with cached converters\n- Opt-in SQL command logging\n- Native SQL `IN` clause expansion\n- Fully provider-agnostic ADO.NET integration\n- No non-Microsoft runtime dependencies\n- Apache 2.0 licensed\n\n---\n\n## 🆕 What’s New in Hydrix 3.0.0\n\n- `Materializer` and `IMaterializer` were removed from the public runtime model.\n- `HydrixDataCore` is now the only supported way to execute commands and queries.\n- Entity Framework interoperability arrived through\n  `HydrixEntityFramework.RegisterModel(...)`, with startup/DI automation via\n  `AddHydrixEntityFrameworkModel\u003cTDbContext\u003e()` and\n  `UseHydrixEntityFrameworkModels()`, allowing Hydrix to read\n  `OnModelCreating` metadata and cache it alongside the existing\n  attribute-based pipeline.\n- `ObjectExtensions` gained faster conversion paths for numeric values,\n  `DateTimeOffset`, `TimeSpan`, and broader boolean aliases.\n- Converter resolution now uses cache entries keyed by `(sourceType, targetType)`.\n- Command and procedure execution hot paths now avoid per-call\n  parameter-binding closures and use atomic hot-cache entries for\n  stronger concurrency correctness.\n- `HydrixOptions` gained `EnableCommandLogging` for explicit logging control.\n- Row materializer execution was tightened through direct delegate invocation and\n  cached `MethodInfo`.\n- Fallback type matching and schema binding were improved to reduce allocations\n  and improve throughput in provider edge cases.\n\n---\n\n## ❗ Breaking Changes in 3.0.0\n\nHydrix 3.0.0 is a **breaking release**.\n\n- `Materializer` was completely removed.\n- `IMaterializer` and all Materializer-based execution/query APIs were removed.\n- Applications must now use the `HydrixDataCore` extension-based API surface.\n\nIf your project is already using the connection extension methods such as `Execute`, `ExecuteScalar`, `Query`, `QueryFirst`, `QuerySingle`, and related overloads, the migration path is straightforward.\n\n---\n\n## 📊 Benchmark Snapshot vs Dapper\n\nThe benchmark suite used for Hydrix 3.0.0 compares Hydrix against ADO.NET,\nDapper, and Entity Framework. The release snapshot below highlights the Dapper\nbaseline:\n\n### Flat\n\n| Scenario | Hydrix | Dapper | Hydrix Gain |\n| --- | ---: | ---: | ---: |\n| Take 1000 | 986.3 us | 1,062.0 us | 7.1% faster |\n| Take 10000 | 10,362.5 us | 12,731.9 us | 18.6% faster |\n\n| Allocation | Hydrix | Dapper | Hydrix Reduction |\n| --- | ---: | ---: | ---: |\n| Take 1000 | 95.77 KB | 166.40 KB | 42.4% less |\n| Take 10000 | 1039.01 KB | 1742.63 KB | 40.4% less |\n\n### Nested\n\n| Scenario | Hydrix | Dapper | Hydrix Gain |\n| --- | ---: | ---: | ---: |\n| Take 1000 | 1.684 ms | 1.744 ms | 3.4% faster |\n| Take 10000 | 17.805 ms | 21.089 ms | 15.6% faster |\n\n| Allocation | Hydrix | Dapper | Hydrix Reduction |\n| --- | ---: | ---: | ---: |\n| Take 1000 | 135.24 KB | 252.84 KB | 46.5% less |\n| Take 10000 | 1430.18 KB | 2602.50 KB | 45.0% less |\n\nHydrix 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.\n\n---\n\n## ⚡ Performance Design in 3.0\n\nHydrix 3.0 continues the performance work started in 2.x and tightens the runtime in a few key places:\n\n- Metadata is built once per type and reused\n- Row materializers use direct delegate invocation in hot paths\n- Command and procedure parameter binding avoid per-call closure allocations\n- Schema binding and matching avoid unnecessary work under contention\n- Converter and binder hot caches use atomic entries for low-overhead correctness under concurrency\n- Conversion fallbacks rely less on generic `Convert.ChangeType`\n- Provider fallback type matching avoids extra boxing when metadata is incomplete\n- Limit-based reads stop as early as possible\n\nThe result is lower GC pressure, more predictable latency, and stronger nested-materialization throughput.\n\n---\n\n## 📦 Installation\n\n```bash\ndotnet add package Hydrix\n```\n\n---\n\n## 🚀 Basic Usage\n\n### Executing SQL Commands\n\n```csharp\nconn.Execute(\n    \"INSERT INTO orders (id, total) VALUES (@id, @total)\",\n    new\n    {\n        id = Guid.NewGuid(),\n        total = 150.75m\n    },\n    timeout: 30\n);\n```\n\n### Querying Entities\n\n```csharp\nvar orders = conn.Query\u003cOrder\u003e(\n    \"SELECT id, total FROM orders WHERE total \u003e @min\",\n    new { min = 100 },\n    timeout: 30\n);\n```\n\n### Native `IN` Clause Support\n\n```csharp\nvar orders = conn.Query\u003cOrder\u003e(\n    \"SELECT * FROM orders WHERE id IN (@ids)\",\n    new\n    {\n        ids = new[] { id1, id2, id3 }\n    }\n);\n```\n\nHydrix automatically expands:\n\n```sql\nWHERE id IN (@ids_0, @ids_1, @ids_2)\n```\n\nEach value is safely parameterized.\n\n---\n\n## 🧩 Configuration \u0026 DI\n\n```csharp\nusing Hydrix.DependencyInjection;\nusing Microsoft.Extensions.DependencyInjection;\n\nvar services = new ServiceCollection();\n\nservices.AddHydrix(options =\u003e\n{\n    options.CommandTimeout = 60;\n    options.ParameterPrefix = \"@\";\n    options.EnableCommandLogging = true;\n});\n```\n\nUse this configuration to centralize timeout, parameter conventions, and logging behavior.\n\nIf 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:\n\n```csharp\nusing Hydrix.DependencyInjection;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.DependencyInjection;\n\nvar services = new ServiceCollection();\n\nservices.AddDbContext\u003cSalesDbContext\u003e(options =\u003e\n    options.UseSqlite(\"Data Source=app.db\"));\n\nservices.AddHydrix();\nservices.AddHydrixEntityFrameworkModel\u003cSalesDbContext\u003e();\n\nusing var serviceProvider = services.BuildServiceProvider();\nserviceProvider.UseHydrixEntityFrameworkModels();\n```\n\n---\n\n## 🤝 Entity Framework Interoperability\n\nHydrix 3.0.0 can work alongside existing Entity Framework models without\nreplacing the current attribute-based approach. You can register the `DbContext`\nor its `Model` manually, or queue the translation through dependency injection\nand execute it once during application startup.\n\n```csharp\nusing Hydrix.DependencyInjection;\nusing Hydrix.EntityFramework;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Extensions.DependencyInjection;\n\n// Manual registration\nusing var dbContext = new SalesDbContext(...);\nHydrixEntityFramework.RegisterModel(dbContext);\nHydrixEntityFramework.RegisterModel(dbContext.Model);\n\n// Startup + DI registration\nvar services = new ServiceCollection();\nservices.AddDbContext\u003cSalesDbContext\u003e(options =\u003e\n    options.UseSqlite(\"Data Source=app.db\"));\nservices.AddHydrix();\nservices.AddHydrixEntityFrameworkModel\u003cSalesDbContext\u003e();\n\nusing var serviceProvider = services.BuildServiceProvider();\nserviceProvider.UseHydrixEntityFrameworkModels();\n```\n\nAfter registration, Hydrix can reuse the table names, schemas, column names,\nkeys, and supported reference navigations defined in `OnModelCreating`.\n\nCurrent 3.0.0 scope:\n\n- additive to the existing DataAnnotations-based pipeline\n- only CLR types that implement `ITable` are registered\n- reference navigations are translated for nested mappings\n- collection navigations are intentionally ignored in 3.0.0\n\n---\n## 🧱 Defining Entities\n\n### Simple Entity\n\n```csharp\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\n[Table(\"orders\", Schema = \"pos\")]\npublic class Order :\n    DatabaseEntity, ITable\n{\n    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]\n    [Column(\"id\")]\n    public Guid Id { get; set; }\n\n    [Column(\"total\")]\n    public decimal Total { get; set; }\n}\n```\n\n### Nested Entities (Flat JOINs)\n\n```csharp\n[Table(\"orders\", Schema = \"pos\")]\npublic class Order :\n    DatabaseEntity, ITable\n{\n    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]\n    [Column(\"id\")]\n    public Guid Id { get; set; }\n\n    [ForeignKey(\"CustomerId\")]\n    [Column(\"customerId\")]\n    public Guid? CustomerId { get; set; }\n\n    [ForeignTable(\"customer\", Schema = \"pos\", PrimaryKeys = new[] { \"Id\" }, ForeignKeys = new[] { \"CustomerId\" })]\n    public Customer Customer { get; set; }\n}\n```\n\nHydrix only materializes nested entities when related data is present, preventing empty object creation in LEFT JOIN scenarios.\n\n### Stored Procedures\n\n```csharp\n[Procedure(\"sp_create_order\", Schema = \"pos\")]\npublic class CreateOrder :\n    DatabaseEntity, IProcedure\u003cSqlParameter\u003e\n{\n    [Parameter(\"p_id\", DbType.Guid)]\n    public Guid Id { get; set; }\n\n    [Parameter(\"p_total\", DbType.Decimal)]\n    public decimal Total { get; set; }\n}\n```\n\n---\n\n## 📝 SQL Command Logging\n\nCommand logging is opt-in and controlled through `HydrixOptions.EnableCommandLogging`.\n\nExample output:\n\n```text\nExecuting DbCommand\nSELECT * FROM orders WHERE id IN (@ids_0, @ids_1)\nParameters:\n  @ids_0 = 'a3f9...' (Guid)\n  @ids_1 = 'b4c1...' (Guid)\n```\n\n---\n\n## 🧩 Provider Compatibility\n\nHydrix works with any ADO.NET-compatible provider:\n\n- SQL Server\n- PostgreSQL\n- MySQL\n- Oracle\n- DB2\n- Others\n\n---\n\n## 🎯 Design Philosophy\n\nHydrix is built around the following principles:\n\n- Explicit SQL\n- Deterministic behavior\n- Performance first\n- No hidden abstractions\n- ADO.NET as a solid foundation\n\n---\n\n## ❤️ Supporting Hydrix\n\nHydrix is an open-source project built and maintained with care, transparency, and a long-term vision.\n\nIf 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.\n\nYou can support Hydrix through GitHub Sponsors:\n\n👉 https://github.com/sponsors/marcelo-mattos\n\nEvery contribution, whether financial or by sharing feedback and usage experiences, is deeply appreciated.\n\n---\n\n## 📄 License\n\nThis project is licensed under the Apache License 2.0.\nSee the LICENSE and NOTICE files for details.\n\n---\n\n## 👨‍💻 Author\n\n**Marcelo Matos dos Santos**\nSoftware Engineer • Open Source Maintainer.\nEngineering clarity. Delivering transformation.\n","funding_links":["https://github.com/sponsors/marcelo-matos","https://github.com/sponsors/marcelo-mattos"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcelo-mattos%2Fhydrix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcelo-mattos%2Fhydrix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcelo-mattos%2Fhydrix/lists"}