IntraDotNet.EFCore.Infrastructure 1.0.1

dotnet add package IntraDotNet.EFCore.Infrastructure --version 1.0.1
                    
NuGet\Install-Package IntraDotNet.EFCore.Infrastructure -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="IntraDotNet.EFCore.Infrastructure" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="IntraDotNet.EFCore.Infrastructure" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="IntraDotNet.EFCore.Infrastructure" />
                    
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 IntraDotNet.EFCore.Infrastructure --version 1.0.1
                    
#r "nuget: IntraDotNet.EFCore.Infrastructure, 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 IntraDotNet.EFCore.Infrastructure@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=IntraDotNet.EFCore.Infrastructure&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=IntraDotNet.EFCore.Infrastructure&version=1.0.1
                    
Install as a Cake Tool

IntraDotNet.EFCore.Infrastructure

A comprehensive .NET library that eliminates boilerplate code when working with Entity Framework Core. This library provides optimisation classes for generating EntityFramework DbContexts, their associated entities, and implementing common functionality like row-based change auditing, soft deleting, optimistic concurrency, repository patterns, and unit of work patterns.

Features

  • Auditable Entities: Automatic tracking of creation and update timestamps
  • Soft Delete: Mark records as deleted without physically removing them from the database
  • Optimistic Concurrency: Built-in row versioning for concurrent access control
  • Repository Pattern: Base repository implementations with common CRUD operations
  • Unit of Work Pattern: Coordinated transaction management across multiple repositories
  • Result Pattern: Structured error handling and operation results
  • Service Layer: Base service classes with validation support
  • Model Builder Extensions: Fluent API extensions for easy EF Core configuration

Getting Started

Prerequisites

  • .NET 9.0 SDK or later
  • Entity Framework Core 9.0 or later
  • IntraDotNet.Domain.Core (>=1.0.0)

Installation

Add the NuGet package to your project:

dotnet add package IntraDotNet.EFCore.Infrastructure

Usage

1. Create Your Entity

using IntraDotNet.Domain.Core;

public class Product : IAuditable, IRowVersion
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    
    // Auditable properties
    public DateTimeOffset CreatedOn { get; set; }
    public DateTimeOffset LastUpdateOn { get; set; }
    public DateTimeOffset? DeletedOn { get; set; }
    
    // Optimistic concurrency
    public byte[] RowVersion { get; set; }
}

2. Configure Your DbContext

public class MyDbContext : DbContext
{
    public DbSet<Product> Products { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // Configure auditing, soft delete, and optimistic concurrency
        modelBuilder.UseAuditable<Product>();
        // Or configure individually:
        // modelBuilder.UseCreateAudit<Product>();
        // modelBuilder.UseUpdateAudit<Product>();
        // modelBuilder.UseSoftDelete<Product>();

        modelBuilder.UseOptimisticConcurrency<Product>();
        
        base.OnModelCreating(modelBuilder);
    }
}

3. Create Your Repository

using IntraDotNet.EFCore.Infrastructure.Repositories;

public class ProductRepository : BaseAuditableRepository<Product, MyDbContext>
{
    public ProductRepository(IDbContextFactory<MyDbContext> contextFactory) 
        : base(contextFactory)
    {
    }
    
    // Add custom repository methods here
    public async Task<IEnumerable<Product>> GetByPriceRangeAsync(decimal minPrice, decimal maxPrice)
    {
        using var context = await GetContextAsync();
        return await GetQueryable(context)
            .Where(p => p.Price >= minPrice && p.Price <= maxPrice)
            .ToListAsync();
    }
}

4. Use Repository in Your Application

// Using repository directly
var repository = new ProductRepository(contextFactory);

// Create a new product
var newProduct = new Product { Name = "Laptop", Price = 999.99m };
await repository.AddOrUpdateAsync(newProduct);

// Get all active products (soft-deleted records are automatically filtered out)
var products = await repository.GetAllAsync();

// Update a product
var product = await repository.GetByIdAsync(1);
if (product != null)
{
    product.Price = 899.99m;
    await repository.AddOrUpdateAsync(product);
}

// Soft delete a product
await repository.DeleteAsync(1);

5. Using with Services

using IntraDotNet.Application.Services;
using IntraDotNet.Application.Results;

public class ProductService : BaseValidatableService<Product>
{
    private readonly ProductRepository _repository;
    
    public ProductService(ProductRepository repository)
    {
        _repository = repository;
    }
    
    public async Task<ValueResult<Product>> CreateProductAsync(string name, decimal price)
    {
        var product = new Product { Name = name, Price = price };
        
        var validationResult = await ValidateAsync(product);
        if (!validationResult.IsSuccess)
            return ValueResult<Product>.Failure(validationResult.Errors);
            
        await _repository.AddAsync(product);
        return ValueResult<Product>.Success(product);
    }
}

Model Builder Extensions

The library provides several extension methods for ModelBuilder to easily configure entity behaviors:

UseAuditable<TEntity>()

Configures an entity with full auditing support (creation, update, and soft delete tracking).

UseCreateAudit<TEntity>()

Configures automatic creation timestamp tracking using CurrentDateTimeValueGenerator.

UseUpdateAudit<TEntity>()

Configures automatic update timestamp tracking.

UseSoftDelete<TEntity>()

Configures soft delete functionality with database indexing for performance.

Note: Due to current EF Core limitations with named query filters, soft-deleted records must be filtered manually or by using the provided repository base classes.

UseOptimisticConcurrency<TEntity>()

Configures row versioning for optimistic concurrency control.

Value Generators

CurrentDateTimeValueGenerator

Automatically generates DateTimeOffset.UtcNow values for auditable timestamp fields.

Repository Pattern

The library provides base repository classes:

  • BaseRepository<TEntity, TContext>: Basic CRUD operations
  • BaseAuditableRepository<TEntity, TContext>: Includes automatic soft-delete filtering

Important Notes

Soft Delete Behavior

Due to current Entity Framework Core limitations with named query filters, the UseSoftDelete extension method does not automatically apply a global query filter. The provided repository base classes handle this filtering, or you can implement it manually in your queries.

There is an open pull request in EF Core to add support for named query filters, which will enable more flexible soft delete filtering in the future.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Contributing

Contributions are welcome! Please submit a pull request on GitHub.

  1. Fork the repository
  2. Create a new branch (git checkout -b feature-branch)
  3. Make your changes
  4. Commit your changes (git commit -am 'Add new feature')
  5. Push to the branch (git push origin feature-branch)
  6. Create a new Pull Request
Product Compatible and additional computed target framework versions.
.NET 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 was computed.  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.1 489 7/23/2025
1.0.0 125 7/8/2025