Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ActiveForge ORM — v1.0.0
We are excited to announce the first release of ActiveForge — a lightweight, Active Record-style ORM for .NET ported and modernised from a proven .NET 3.5 foundation. ActiveForge brings type-safe persistence, composable querying, LINQ support, nested transactions, and DI-friendly service proxying to .NET 8 through .NET 10, with provider support for SQL Server, PostgreSQL, MongoDB, and SQLite.
Packages
ActiveForge.CoreActiveForge.SqlServerMicrosoft.Data.SqlClientActiveForge.PostgreSQLActiveForge.MongoDBActiveForge.SQLiteMicrosoft.Data.Sqlite, including in-memory database supportWhat's included
Entities & Mapping
Entities follow the Active Record pattern — state and persistence logic live together in the same class, eliminating the need for a separate repository layer. Entities are defined once and work across all providers without modification.
Type-safe fields replace plain CLR properties with wrapper types (
TString,TInt,TDecimal,TBool,TDateTime,TForeignKey, and 20+ more). Each field tracks its own nullability and dirty state, handles value conversion automatically, and participates in change detection for partial updates.Attributes control the mapping between entity fields and the underlying store:
[Table][Column][Identity][ReadOnly][NoPreload]FieldSubset[DefaultValue][Encrypted][Sensitive]Additional mapping capabilities: polymorphic mapping (base type resolved to concrete subtype at runtime), custom field mappers for non-standard type conversions, and field subsets for loading or updating only a named subset of columns.
Querying
QueryTerm API — build queries by composing predicate objects:
EqualTerm,ContainsTerm,LikeTerm,NullTerm,RangeTerm,GreaterOrEqualTerm,LessOrEqualTerm, and their logical combinations. Sort withOrderAscending/OrderDescendingincluding multi-columnCombinedSortOrder.LINQ support —
conn.Query<T>()returns anIQueryable<T>that translatesWhere,OrderBy,ThenBy,Take, andSkipinto native ORM operations. Cross-join predicates and sort are fully supported — filter or order by a field on an embedded (joined) entity directly in the lambda:Join type overrides — class-level join types (
INNER JOIN/LEFT OUTER JOIN) can be overridden per query without changing the entity definition:Pagination —
QueryPagereturns results with total-count metadata. Lazy streaming —LazyQueryAllyields rows one at a time for memory-efficient processing of large result sets.Transactions & Unit of Work
ActiveForge provides three complementary ways to manage transactions:
With.Transaction— wrap an ad-hoc block of work:IUnitOfWork— fine-grained programmatic control withCreateTransaction,Commit, andRollback. Nesting is depth-tracked; only the outermost scope commits to the database.[Transaction]attribute — declarative demarcation via Castle DynamicProxy. Applying the attribute to a service method causes the proxy to open the connection, begin the transaction, commit on success, and roll back and close the connection on exception — with no virtual methods or base class coupling required.Dependency Injection & Service Proxy
ActiveForge integrates with any .NET DI host (ASP.NET Core, Worker Service, console) through provider-specific
IServiceCollectionextension methods.One-call registration:
IServicemarker — implementIServiceon any class to opt it into auto-discovery.AddServices()scans the supplied assemblies, registers each implementation against its non-system interfaces, and wraps it in a Castle interface proxy that activates[Transaction]and[ConnectionScope]interceptors transparently.ActiveForgeServiceFactory— available for standalone (non-DI) scenarios where a proxy is needed without a container.Provider highlights
SQL Server
Microsoft.Data.SqlClient5.2.1SELECT @@IDENTITYfor identity retrieval (compatible withsp_executesqlexecution scope)PostgreSQL
RETURNINGclause for identity retrieval after insertFOR UPDATEsemanticsMongoDB
QueryTermpredicates translate to MongoDBFilterDefinition($eq,$in,$gte,$lte, regex forLikeTerm)$lookup+$unwindaggregation pipeline for embedded Record fields (joins)__activeforge_counterscollection;[Identity]maps to_idMongoUnitOfWorkSQLite
Microsoft.Data.Sqlite8.0.0 adapter layerData Source=:memory:) — ideal for fast integration tests without a serverTarget Frameworks
ActiveForge.Corenet8.0·net9.0·net10.0·net472·netstandard2.0·netstandard2.1ActiveForge.SqlServernet8.0·net9.0·net10.0·net472·netstandard2.0·netstandard2.1ActiveForge.PostgreSQLnet8.0·net9.0·net10.0(limited by Npgsql 8)ActiveForge.SQLitenet8.0·net9.0·net10.0·netstandard2.0·netstandard2.1ActiveForge.MongoDBnet8.0·net9.0·net10.0·net472·netstandard2.0·netstandard2.1Test coverage
679 tests — 0 failures across all five providers.
Each provider suite covers full CRUD, join queries, pagination, transactions, and Unit of Work lifecycle.
Documentation
TFieldtypes, operators, and conversion behaviourWHERE,ORDER BY, pagination, and joinsIUnitOfWork,With.Transaction,[Transaction], service proxiesconn.Query<T>(), cross-join predicates, join overridesContributing
Bug reports, feature requests, and pull requests are welcome — please see CONTRIBUTING.md for guidelines.
Full commit history: https://github.com/CodeShayk/ActiveForge/commits/v1.0.0