AwadyLab.EFCatalyst 1.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package AwadyLab.EFCatalyst --version 1.0.1
                    
NuGet\Install-Package AwadyLab.EFCatalyst -Version 1.0.1
                    
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="AwadyLab.EFCatalyst" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AwadyLab.EFCatalyst" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="AwadyLab.EFCatalyst" />
                    
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 AwadyLab.EFCatalyst --version 1.0.1
                    
#r "nuget: AwadyLab.EFCatalyst, 1.0.1"
                    
#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 AwadyLab.EFCatalyst@1.0.1
                    
#: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=AwadyLab.EFCatalyst&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=AwadyLab.EFCatalyst&version=1.0.1
                    
Install as a Cake Tool

AwadyLab.EFCatalyst

An Entity Framework Core 10 toolkit for the things most line-of-business data layers rebuild by hand: auditable, soft-deletable and multi-tenant entities, named global query filters, LINQ helpers for filtering, sorting and paging, a SaveChanges pipeline, column encryption, change-tracking audit logs and migration helpers for views, triggers, upserts and filtered indexes.

Tests Target Language License


Overview

AwadyLab.EFCatalyst plugs into an ordinary DbContext: entities implement small interfaces (or derive from the provided bases), the model picks up the matching conventions and filters, and a set of interceptors does the auditing, tenancy and soft-delete work on every save. Targets .NET 10 and EF Core 10.

There are five packages, and they ship in lockstep:

Package What it adds
AwadyLab.EFCatalyst.Abstraction Contracts and entity bases (entity interfaces and base classes, domain events, global filters, seeders, service abstractions) for domain projects. See its README.
AwadyLab.EFCatalyst Every provider-neutral feature in this document (references the abstractions).
AwadyLab.EFCatalyst.SqlServer Native rowversion, deadlock detection, T-SQL for the migration helpers. See its README.
AwadyLab.EFCatalyst.PostgreSql Deadlock detection, PostgreSQL SQL for the migration helpers. See its README.
AwadyLab.EFCatalyst.Sqlite Sortable DateTimeOffset storage, busy/locked detection, SQLite SQL for the migration helpers. See its README.

Key Highlights

  • Entities That Audit Themselves: Implement ICreationAudited, IModificationAudited, IDeletionAudited or ITenantEntity<T> (or derive from FullAuditedAggregateRoot<TKey>) and the save pipeline stamps the audit columns, assigns the tenant and turns deletes into soft deletes.
  • Named Global Filters: Soft delete and tenant isolation are applied as named query filters, so one query can switch one of them off (IncludeSoftDeleted, IgnoreTenantFilter) without losing the other.
  • One SaveChanges Pipeline: Audit, tenant guard, soft delete, concurrency, validation, integrity hashing and domain events run in a single pass that detects changes once and walks the change set once.
  • Column Security: StoreEncrypted (AES-256-GCM), StoreMasked and StorePermutated, configured with the fluent API only.
  • Migrations Beyond Tables: Idempotent seed data, upserts, views, functions, filtered and soft-delete indexes, and soft-delete and timestamp triggers, generated per provider.
  • Low-Allocation Hot Paths: Per-entity-type metadata is computed once per model; expression trees and reflection are cached; crypto and naming code works on pooled or stack buffers.
  • A Tracked Public API: Every public symbol is declared in PublicAPI.*.txt; everything else is internal.

Installation

dotnet add package AwadyLab.EFCatalyst
dotnet add package AwadyLab.EFCatalyst.SqlServer     # or .PostgreSql / .Sqlite, next to the EF Core provider
dotnet add package AwadyLab.EFCatalyst.Abstraction   # optional, domain projects that only need the contracts

Quickstart

1. Define an entity

public sealed class Order : FullAuditedAggregateRoot<int>, ITenantEntity<int>
{
    public decimal Total { get; private set; }
    public int TenantId { get; private set; }
    public void Place() => AddDomainEvent(new OrderPlaced(Id));
}

2. Configure the context

public sealed class ShopContext(DbContextOptions<ShopContext> options) : DbContext(options)
{
    public DbSet<Order> Orders => Set<Order>();

    protected override void ConfigureConventions(ModelConfigurationBuilder b) =>
        b.ConfigureDecimalPrecision(18, 2).ConfigureDateTimeUtc();

    protected override void OnModelCreating(ModelBuilder modelBuilder) =>
        modelBuilder.AddDefaultQueryFilters(this);            // soft delete + tenant, as named filters
}

3. Register in DI (Program.cs)

services.AddEFCatalyst(o => o.Features.Validation = true);
services.AddScoped<ICurrentUserAccessor, HttpUserAccessor>();   // audit user
services.AddScoped<ICurrentTenantAccessor<int>, HttpTenantAccessor>(); // current tenant, read per query
services.AddScoped<IDomainEventDispatcher, MediatorDispatcher>(); // optional
services.AddDbContext<ShopContext>((sp, o) => o
    .UseSqlServer(connectionString)
    .UseEFCatalystSqlServer()
    .UseEFCatalystInterceptors(sp));

Removing an Order now sets IsDeleted, DeletedAtUtc and DeletedBy; creating and updating stamp the audit columns; new rows get the context's tenant and writes to another tenant's rows are rejected; the placed event is dispatched after the save succeeds.


1. Domain Model

Entity interfaces: IEntity<TKey>, ISoftDelete, IDeletionAudited, ICreationAudited, IModificationAudited, IAuditEntity, IFullAudited, ITenantEntity<T>, IRowVersion, IActiveState, IHashableEntity.

Base classes: Entity, AuditedEntity, SoftDeleteEntity, DeletionAuditedEntity, FullAuditedEntity, TenantEntity, AggregateRoot, FullAuditedAggregateRoot.

Details: docs/domain.md.


2. Querying

  • Conditional filters: WhereIf, WhereIfNotNull, WhereIfNotNullOrWhiteSpace, WhereIfNotEmpty, WhereExists / WhereNotExists, chunked WhereIn / WhereNotIn.
  • Sorting: OrderByIf / ThenByIf, OrderByProperty, ApplySorting.
  • Paging: PageBy, ToPagedListAsync, keyset Slice / ToCursorPageAsync.
  • Loading and tracking: IncludeIf, AsNoTrackingIf, IgnoreQueryFiltersIf.
  • Filter switches: IncludeSoftDeleted, OnlySoftDeleted, IncludeInactive, IgnoreTenantFilter.
  • Bulk soft delete: ExecuteSoftDeleteAsync, ExecuteRestoreAsync.
  • Hierarchies: recursive GetDescendantsAsync / GetAncestorsAsync.

Details: docs/querying.md.


3. Interceptors

The save pipeline, slow-query logging, query tagging and deadlock retry.

Details: docs/interceptors.md.


4. Model Building

IGlobalFilter<T> with AddGlobalQueryFilterInterfacesInAssembly, configuration bases, UTC DateTime and decimal precision conventions.

Details: docs/model-building.md.


5. Column Security

StoreEncrypted (AES-256-GCM), StoreMasked and StorePermutated, configured with the fluent API only.

Details: docs/security.md.


6. Shadow Properties & Change Tracking

Typed shadow accessors, WhereShadowEquals, GetChangedProperties, HasPropertyChanged, GetOriginalValue and ToAuditEntryList.

Details: docs/change-tracking.md.


7. Schema & Migrations

  • Schema: GetTableName, GetColumnName, GetPrimaryKeys, GetMappedProperties.
  • Database lifecycle: EnsureDatabaseDeletedAndRecreatedAsync, HasPendingMigrationsAsync, IMigrationSeeder.
  • Migration helpers: InsertDataIfMissing, UpsertData, DeleteDataIfExists, views, functions, filtered and soft-delete indexes, soft-delete and timestamp triggers.

Details: docs/migrations.md.


8. Providers

Enable a provider package next to the EF Core provider:

options.UseSqlServer(cs).UseEFCatalystSqlServer();
options.UseNpgsql(cs).UseEFCatalystPostgreSql();
options.UseSqlite(cs).UseEFCatalystSqlite();                  // or UseEFCatalystSqlite(o => ...)

Each provider package registers its own migrations SQL generator. If you replace IMigrationsSqlGenerator yourself, derive from the EFCatalyst one or call the provider package after your replacement.

Details: docs/providers.md.


9. Performance & Security

  • Performance: per-entity-type metadata is computed once per model (runtime annotations); the save pipeline detects changes once and walks the change set once; expression trees and reflection are cached; crypto and naming code works on pooled or stack buffers. AwadyLab.EFCatalyst.Benchmarks compares the pipeline with plain EF.
  • Security: values in migration helpers are provider-typed literals and identifiers are always quoted; dynamic sorting only binds public properties; cursors can be HMAC-signed; sensitive columns are redacted from audit entries and never appear in exception messages; query tags are sanitised. See docs/security.md.

Sample App

SampleApp is organised like an application (Domain/, Data/ with configurations, filters and seeders, Infrastructure/ with the composition root in SampleHost) and runs one scenario per feature area, each on a freshly seeded database: model, tenancy, auditing, soft-delete, security, integrity, concurrency, validation, events, change-tracking, querying, hierarchy, seeding, migrations, diagnostics.

dotnet run --project SampleApp                      # guided tour on SQLite, every scenario
dotnet run --project SampleApp -- tenancy security  # selected scenarios

Building

./build.ps1          # build, unit tests, coverage gate (eng/coverage.json) and report in ../coverage-report
./build.ps1 -Pack    # also pack and verify the five packages
dotnet test AwadyLab.EFCatalyst.Tests.Integration   # SQL Server + PostgreSQL containers (Docker)

License

Package by Mohamed Elawady

Copyright (c) Mohamed Elawady. All rights reserved.

This software is closed source and proprietary. Subject to the terms below,
you are granted a free, worldwide, non-exclusive license to:

  - Use this software, in source or compiled (NuGet package) form, in your
    own applications, including commercial applications, at no charge.

You may NOT:

  - Redistribute, sublicense, sell, or publish this software (or any
    modified version of it) as a standalone product, library, or package,
    including republishing it under a different name on NuGet.org or any
    other package repository.
  - Reverse engineer, decompile, or disassemble the compiled package except
    to the extent applicable law expressly permits this despite this
    limitation.
  - Remove or alter any copyright, trademark, or other proprietary notices.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Product Compatible and additional computed target framework versions.
.NET 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on AwadyLab.EFCatalyst:

Package Downloads
AwadyLab.EFCatalyst.SqlServer

SQL Server support for AwadyLab.EFCatalyst: native rowversion concurrency, deadlock detection and T-SQL generation for the EFCatalyst migration operations (views, upserts, soft-delete and timestamp triggers, filtered indexes).

AwadyLab.EFCatalyst.PostgreSql

PostgreSQL (Npgsql) support for AwadyLab.EFCatalyst: deadlock detection and SQL generation for the EFCatalyst migration operations (views, functions, ON CONFLICT upserts, soft-delete and timestamp triggers, filtered indexes).

AwadyLab.EFCatalyst.Sqlite

SQLite support for AwadyLab.EFCatalyst: sortable DateTimeOffset storage, busy/locked detection and SQL generation for the EFCatalyst migration operations (views, upserts, soft-delete and timestamp triggers, filtered indexes).

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 121 10/2/2026
1.0.1 118 10/2/2026
1.0.0 131 9/30/2026