ActiveForge.Core 1.0.0

dotnet add package ActiveForge.Core --version 1.0.0
                    
NuGet\Install-Package ActiveForge.Core -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ActiveForge.Core" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ActiveForge.Core" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="ActiveForge.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ActiveForge.Core --version 1.0.0
                    
#r "nuget: ActiveForge.Core, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ActiveForge.Core@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ActiveForge.Core&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=ActiveForge.Core&version=1.0.0
                    
Install as a Cake Tool

A lightweight, Active Record-style ORM for .NET with first-class support for SQL Server, PostgreSQL, and MongoDB.


Packages

Package Description
NuGet version Core — entities, fields, predicates, LINQ, transactions, adapters, Castle proxy factory
NuGet version SQL Server provider — SqlServerConnection, ADO.NET adapters, SqlServerUnitOfWork, DI extensions
NuGet version PostgreSQL provider — PostgreSQLConnection, Npgsql adapters, PostgreSQLUnitOfWork, DI extensions
NuGet version MongoDB provider — MongoDataConnection, BSON mapping, MongoUnitOfWork, DI extensions
NuGet version SQLite provider — SQLiteConnection, Microsoft.Data.Sqlite adapters, SQLiteUnitOfWork, DI extensions

All connection types live in the ActiveForge namespace, so a single using ActiveForge; is sufficient regardless of the provider chosen.


Features

ActiveForge streamlines data-centric development with a cohesive approach to entities, queries, and data management.

🗂 Entities & Mapping

  • Active Record pattern
    Entities contain both state and persistence logic, removing the need for external repositories.
  • Type-safe fields
    Provides wrappers for types (string, int, decimal, keys, etc.), tracking nullability and state, and handling conversion automatically.
  • Polymorphic mapping
    Maps base types to concrete subtypes at runtime.
  • Custom field mappers
    Easily support non-standard type conversions.
  • Field encryption
    Simple attribute-based encryption/decryption for sensitive data.

🔍 Querying

  • Composable predicates
    Build queries with terms for equality, containment, ranges, null checks, and pattern matching; combine them with logical operators.
  • LINQ support
    Write queries using familiar C# syntax, auto-translated to efficient ORM operations.
  • Pagination
    Built-in paging with metadata for efficient handling of large datasets.
  • Lazy streaming
    Stream results row-by-row for memory efficiency.
  • Field subsets
    Load or update only the fields you need.

💾 Data Management

  • Transactions
    Explicit and nested transaction support; control scope via code or attributes.
  • Unit of Work
    Integrated pattern for grouping multiple changes; supports both code-based and attribute-based usage.
  • Connection lifecycle
    Connections and transactions are managed automatically on every write, ensuring reliability.
  • Batch operations
    Queue up changes and execute them in bulk to reduce database round-trips.

🌐 Dependency Injection & Service Proxy

  • Auto-discovery & registration
    Services marked with a simple interface are discovered and registered automatically.
  • Fluent builder API
    Register all or selected services with fine-grained control.
  • Seamless DI integration
    Simplifies service composition, testing, and enables proxy/interceptor scenarios.

Quick Start

1. Connect (standalone)

using ActiveForge;

// SQL Server
var conn = new SqlServerConnection(
    "Server=.;Database=Demo;Integrated Security=True;TrustServerCertificate=True;");

// PostgreSQL
var conn = new PostgreSQLConnection(
    "Host=localhost;Database=demo;Username=app;Password=secret;");

// MongoDB
var conn = new MongoDataConnection(
    "mongodb://localhost:27017",
    "demo");

// SQLite
var conn = new SQLiteConnection("Data Source=app.db");

conn.Connect();

2. Register with DI

Works in any DI host — ASP.NET Core, Worker Service, console, etc. The provider-specific AddActiveForge* call registers the connection + UoW and returns an IActiveForgeBuilder. Chain .AddServices() to auto-scan your assembly for IService implementations.

// Program.cs — choose one provider, then scan for IService implementations:
builder.Services
    .AddActiveForgeSqlServer(
        "Server=.;Database=Demo;Integrated Security=True;TrustServerCertificate=True;")
    .AddServices(typeof(Program).Assembly);

builder.Services
    .AddActiveForgePostgreSQL("Host=localhost;Database=demo;Username=app;Password=secret;")
    .AddServices(typeof(Program).Assembly);

builder.Services
    .AddActiveForgeMongoDB("mongodb://localhost:27017", "demo")
    .AddServices(typeof(Program).Assembly);

builder.Services
    .AddActiveForgeSQLite("Data Source=app.db")
    .AddServices(typeof(Program).Assembly);

3. Define entities

Entity classes are provider-agnostic — the same class works with SQL Server, PostgreSQL, MongoDB, and SQLite.

using ActiveForge;
using ActiveForge.Attributes;

[Table("categories")]
public class Category : IdentityRecord
{
    [Column("name")] public TString Name = new TString();

    public Category() { }
    public Category(DataConnection conn) : base(conn) { }
}

[Table("products")]
public class Product : IdentityRecord
{
    [Column("name")]        public TString     Name       = new TString();
    [Column("price")]       public TDecimal    Price      = new TDecimal();
    [Column("in_stock")]
    [DefaultValue(true)]    public TBool       InStock    = new TBool();
    [Column("created_at")]
    [ReadOnly]              public TDateTime   CreatedAt  = new TDateTime();
    [Column("notes")]
    [NoPreload]             public TString     Notes      = new TString();
    [Column("CategoryID")]  public TForeignKey CategoryID = new TForeignKey();

    // Embedded Record — triggers automatic INNER JOIN in queries
    public Category Category;

    public Product()                          { Category = new Category(); }
    public Product(DataConnection conn) : base(conn) { Category = new Category(conn); }
}

Naming conventions: PostgreSQL folds unquoted identifiers to lower-case — use lower-case [Table] and [Column] values. MongoDB uses the attribute values as BSON field and collection names verbatim.

Key attributes: [ReadOnly] — included in SELECT but never written. [NoPreload] — excluded from the default SELECT; include via FieldSubset. [DefaultValue] — pre-populates the field on construction. [Sensitive] — masks values in diagnostic output. [Encrypted] — transparent encrypt/decrypt at ORM layer.

4. CRUD

using ActiveForge.Query;
using ActiveForge.Linq;

// ── INSERT ────────────────────────────────────────────────────────────────────
var p = new Product(conn);
p.Name.SetValue("Widget");
p.Price.SetValue(9.99m);
p.InStock.SetValue(true);
p.Insert();   // p.ID is populated automatically after insert

// ── READ by primary key ───────────────────────────────────────────────────────
var p2 = new Product(conn);
p2.ID.SetValue(1);
p2.Read();   // throws PersistenceException if not found

// ── QUERY (QueryTerm API) ─────────────────────────────────────────────────────
var template = new Product(conn);
var inStock  = new EqualTerm(template, template.InStock, true);
var byName   = new OrderAscending(template, template.Name);
var results  = conn.QueryAll(template, inStock, byName, 0, null);

// ── QUERY (LINQ) ──────────────────────────────────────────────────────────────
List<Product> page = conn.Query(new Product(conn))
    .Where(x => x.InStock == true && x.Price < 50m)
    .OrderBy(x => x.Name)
    .Skip(0).Take(20)
    .ToList();

// ── QUERY with JOIN filter ────────────────────────────────────────────────────
List<Product> electronics = conn.Query(new Product(conn))
    .Where(x => x.Category.Name == "Electronics")
    .OrderBy(x => x.Price)
    .ToList();

// ── UPDATE ────────────────────────────────────────────────────────────────────
p.Price.SetValue(14.99m);
p.Update(RecordLock.UpdateOption.IgnoreLock);   // update all columns

p.Notes.SetValue("On sale");
p.UpdateChanged();                              // update only changed columns

// ── DELETE ────────────────────────────────────────────────────────────────────
p.Delete();                                     // delete by PK

// Delete by predicate:
var disc = new EqualTerm(template, template.InStock, false);
template.Delete(disc);

5. Service proxy — automatic connection & transaction management

Implement IService on your class alongside a service interface. Castle DynamicProxy handles open → begin → commit → close with no virtual methods or framework coupling required.

using ActiveForge;
using ActiveForge.Transactions;

// ── Interface (consumed by controllers / other services)
public interface IOrderService
{
    Order GetById(int id);
    void  Ship(int orderId);
}

// ── Implementation — IService triggers auto-registration
public class OrderService : IOrderService, IService
{
    private readonly DataConnection _conn;
    public OrderService(DataConnection conn) { _conn = conn; }

    public Order GetById(int id) { ... }

    [Transaction]                   // opens connection, begins tx, commits/rolls back, closes connection
    public void Ship(int orderId)
    {
        var order = new Order(_conn);
        order.ID.SetValue(orderId);
        _conn.Read(order);
        order.Status.SetValue("Shipped");
        order.Update(RecordLock.UpdateOption.IgnoreLock);
        // commit on success; rollback + connection close on exception
    }
}

// Register — auto-scan picks up OrderService, registers as IOrderService:
builder.Services
    .AddActiveForgeSqlServer("Server=...;...")
    .AddServices(typeof(Program).Assembly);

// Inject by interface — proxy is transparent:
public class CheckoutController : ControllerBase
{
    public CheckoutController(IOrderService orders) { _orders = orders; }
    [HttpPost("{id}/ship")]
    public IActionResult Ship(int id) { _orders.Ship(id); return NoContent(); }
}

Manual usage (standalone, no DI):

var conn = new SqlServerConnection("...");
var uow  = new SqlServerUnitOfWork(conn);
var svc  = ActiveForgeServiceFactory.Create(new OrderService(conn), conn, uow);
svc.Ship(42);

// Or With.Transaction for ad-hoc work:
With.Transaction(uow, () =>
{
    order.Status.SetValue("Shipped");
    order.Update(RecordLock.UpdateOption.IgnoreLock);
    shipment.Insert();
});

Documentation

Guide Description
Getting Started Step-by-step tutorial
Field Types All TField types and their operators
Query Builder Composing WHERE, ORDER BY, and pagination
Transactions & DI Manual transactions, IUnitOfWork, With.Transaction, [Transaction] interceptor, DI service proxies
LINQ Querying conn.Query<T>() LINQ support
Field Subsets Partial fetches and partial updates
Advanced Encryption, custom mappers, polymorphism
Wiki Comprehensive reference — all concepts with examples

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 is compatible.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on ActiveForge.Core:

Package Downloads
ActiveForge.SQLite

Provides SQLite adapter for ActiveForge ORM. Provides type-safe fields, composable query predicates, LINQ query translation, nested transactions, Unit of Work and DI auto-scan.

ActiveForge.MongoDB

Provides MongoDB adapter for ActiveForge ORM. Provides type-safe fields, composable query predicates, LINQ query translation, nested transactions, Unit of Work and DI auto-scan.

ActiveForge.SqlServer

Provides SQL Server adapter for ActiveForge ORM. Provides type-safe fields, composable query predicates, LINQ query translation, nested transactions, Unit of Work and DI auto-scan.

ActiveForge.PostgreSQL

Provides PostgreSQL adapter for ActiveForge ORM. Provides type-safe fields, composable query predicates, LINQ query translation, nested transactions, Unit of Work and DI auto-scan.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 37 3/13/2026

### v1.0.0 Highlights
     - Active Record pattern — entities contain both state and persistence logic
     - 25+ type-safe field types with nullability tracking and automatic conversion
     - Composable predicates (equality, containment, ranges, null checks, pattern matching)
     - Full LINQ query support with auto-translation to ORM operations
     - Built-in pagination with metadata and lazy streaming for memory efficiency
     - Explicit and nested transaction support with `[Transaction]` attribute interception
     - Unit of Work pattern for grouping multiple changes
     - Batch operations for reducing database round-trips
     - Field encryption via `[Encrypted]` attribute
     - Polymorphic mapping and custom field mappers
     - DI auto-discovery and fluent builder API