Imagile.Framework.EntityFrameworkCore 0.1.140

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

Imagile.Framework.EntityFrameworkCore

EF Core audit logging with automatic timestamps, user tracking, property-level change tracking, and soft delete support. Provides opinionated interfaces and base DbContext for building auditable applications.

Installation

dotnet add package Imagile.Framework.EntityFrameworkCore

Features

  • Automatic Timestamps - ITimestampedEntity interface with CreatedOn/ModifiedOn tracking
  • User Tracking - IAuditableEntity interface for CreatedBy/ModifiedBy/DeletedBy
  • Property-Level Change Tracking - IEntityChangeAuditable for detailed audit trails (old value → new value)
  • Soft Delete Support - IsDeleted, DeletedOn, DeletedBy with automatic population
  • Tenant Isolation - ITenantEntity interface for multi-tenant applications
  • ImagileDbContext Base Class - Automatic audit processing in SaveChanges override

Usage Examples

Basic Timestamp Tracking

Use ITimestampedEntity for simple created/modified timestamp tracking:

using Imagile.Framework.EntityFrameworkCore.Interfaces;

public class BlogPost : ITimestampedEntity
{
    public int Id { get; set; }
    public string Title { get; set; } = string.Empty;
    public string Content { get; set; } = string.Empty;

    // ITimestampedEntity - automatically managed
    public DateTimeOffset CreatedOn { get; set; }
    public DateTimeOffset ModifiedOn { get; set; }
}

public class MyDbContext : ImagileDbContext<int, int>
{
    public MyDbContext(
        DbContextOptions<MyDbContext> options,
        IAuditContextProvider<int, int> auditContext)
        : base(options, auditContext)
    {
    }

    public DbSet<BlogPost> BlogPosts => Set<BlogPost>();
}

// Usage - timestamps are automatic
var post = new BlogPost { Title = "Hello World", Content = "..." };
context.BlogPosts.Add(post);
await context.SaveChangesAsync();
// post.CreatedOn and post.ModifiedOn now populated with UTC timestamp

Full Audit with User Tracking and Soft Delete

Use IAuditableEntity<TUserKey> for comprehensive audit trails including who made changes:

using Imagile.Framework.EntityFrameworkCore.Interfaces;

public class Customer : IAuditableEntity<int>
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;

    // ITimestampedEntity
    public DateTimeOffset CreatedOn { get; set; }
    public DateTimeOffset ModifiedOn { get; set; }

    // IAuditableEntity - user tracking
    public int? CreatedBy { get; set; }
    public int? ModifiedBy { get; set; }

    // IAuditableEntity - soft delete
    public bool IsDeleted { get; set; }
    public DateTimeOffset? DeletedOn { get; set; }
    public int? DeletedBy { get; set; }
}

// Implement audit context provider (from HttpContext, claims, etc.)
public class HttpAuditContextProvider : IAuditContextProvider<int, int>
{
    private readonly IHttpContextAccessor _httpContext;

    public HttpAuditContextProvider(IHttpContextAccessor httpContext)
    {
        _httpContext = httpContext;
    }

    public int? UserId => GetUserIdFromClaims();
    public int? TenantId => GetTenantIdFromClaims();

    private int? GetUserIdFromClaims()
    {
        var claim = _httpContext.HttpContext?.User?.FindFirst("sub");
        return claim != null && int.TryParse(claim.Value, out var id) ? id : null;
    }

    private int? GetTenantIdFromClaims()
    {
        var claim = _httpContext.HttpContext?.User?.FindFirst("tenant_id");
        return claim != null && int.TryParse(claim.Value, out var id) ? id : null;
    }
}

// Register in DI
builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped<IAuditContextProvider<int, int>, HttpAuditContextProvider>();

// Usage - all audit fields populated automatically
var customer = new Customer { Name = "Acme Corp", Email = "contact@acme.com" };
context.Customers.Add(customer);
await context.SaveChangesAsync();
// customer.CreatedBy now contains current user ID from HttpContext

// Soft delete - automatically populates DeletedOn and DeletedBy
customer.IsDeleted = true;
await context.SaveChangesAsync();
// customer.DeletedOn and customer.DeletedBy now populated

// Apply global query filter to exclude soft-deleted entities
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Customer>().HasQueryFilter(c => !c.IsDeleted);
    base.OnModelCreating(modelBuilder);
}

Property-Level Change Tracking

Use IEntityChangeAuditable<TUserKey> for detailed audit trails recording old value → new value changes:

using Imagile.Framework.EntityFrameworkCore.Interfaces;
using Imagile.Framework.EntityFrameworkCore.Attributes;

public class Invoice : IEntityChangeAuditable<int>
{
    public int Id { get; set; }

    [Auditable]
    public decimal Amount { get; set; }

    [Auditable]
    public string Status { get; set; } = string.Empty;

    public string Notes { get; set; } = string.Empty; // NOT audited (no [Auditable])

    // IEntityChangeAuditable implementation
    public int? ItemId => Id == 0 ? null : Id;
    public string? ParentEntityName => null;
    public int? ParentItemId => null;
    public string? EntityChangeDescription => $"Invoice #{Id}";

    // IAuditableEntity properties
    public DateTimeOffset CreatedOn { get; set; }
    public DateTimeOffset ModifiedOn { get; set; }
    public int? CreatedBy { get; set; }
    public int? ModifiedBy { get; set; }
    public bool IsDeleted { get; set; }
    public DateTimeOffset? DeletedOn { get; set; }
    public int? DeletedBy { get; set; }
}

// Configure your DbContext to include EntityChange and EntityChangeProperty
public class MyDbContext : ImagileDbContext<int, int>
{
    public MyDbContext(
        DbContextOptions<MyDbContext> options,
        IAuditContextProvider<int, int> auditContext)
        : base(options, auditContext)
    {
    }

    public DbSet<Invoice> Invoices => Set<Invoice>();

    // Required for property-level change tracking
    public DbSet<EntityChange> EntityChanges => Set<EntityChange>();
    public DbSet<EntityChangeProperty> EntityChangeProperties => Set<EntityChangeProperty>();
}

// Usage - property changes automatically tracked
var invoice = context.Invoices.Find(123);
invoice.Amount = 1500.00m; // Changed from 1000.00
invoice.Status = "Approved"; // Changed from "Pending"
invoice.Notes = "Updated notes"; // NOT tracked (no [Auditable])
await context.SaveChangesAsync();

// EntityChange record created with:
// - EntityName: "Invoice"
// - ItemId: 123
// - Description: "Invoice #123"
// - TransactionUnique: [generated GUID]
// - ModifiedBy: [current user ID]
// - ModifiedOn: [current UTC timestamp]

// EntityChangeProperty records created:
// - PropertyName: "Amount", OldValue: "1000.00", NewValue: "1500.00"
// - PropertyName: "Status", OldValue: "Pending", NewValue: "Approved"
// (Notes change NOT recorded - no [Auditable] attribute)

Key Types

Interfaces

  • ITimestampedEntity - Basic timestamp tracking (CreatedOn, ModifiedOn)
  • IAuditableEntity<TUserKey> - Full audit with user tracking and soft delete
  • IEntityChangeAuditable<TUserKey> - Property-level change tracking
  • ITenantEntity<TTenantKey> - Multi-tenant isolation
  • IAuditContextProvider<TUserKey, TTenantKey> - Provides current user/tenant IDs

Base Classes

  • ImagileDbContext<TUserKey, TTenantKey> - Base DbContext with automatic audit processing in SaveChanges

Entities

  • EntityChange - Tracks entity-level changes (what entity, when, by whom)
  • EntityChangeProperty - Tracks property-level changes (old value → new value)

Attributes

  • [Auditable] - Mark properties for detailed change tracking (used with IEntityChangeAuditable)

Dependencies

Requires Imagile.Framework.Core package.

License

MIT License - see LICENSE file for details.

Contributing

Contributions are welcome! Please open an issue or pull request on GitHub.

Repository

https://github.com/imagile/imagile-framework

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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.12 72 3/21/2026
1.0.11 72 3/21/2026
1.0.10 69 3/21/2026
1.0.9 70 3/20/2026
1.0.8 84 3/15/2026
1.0.7 85 2/23/2026
1.0.6 106 2/2/2026
1.0.5 144 2/1/2026
1.0.2 95 1/31/2026
1.0.0 95 1/31/2026
0.1.140 95 1/31/2026
0.0.1 98 1/31/2026