Indiko.Blocks.DataAccess.EntityFramework 2.1.0

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

Indiko.Blocks.DataAccess.EntityFramework

Entity Framework Core implementation of the Indiko data access abstractions, providing full-featured ORM support for relational databases.

Overview

This package provides a complete Entity Framework Core implementation of the Indiko data access layer, supporting SQL Server, PostgreSQL, MySQL, SQLite, and other relational databases.

Features

  • EF Core Integration: Full Entity Framework Core 9+ support
  • Repository Implementation: Complete IRepository<TEntity, TIdType> implementation
  • Unit of Work: Transaction management with EF Core
  • DbContext: Base DbContext with automatic configuration
  • Migrations Support: Full EF Core migrations support
  • Change Tracking: Automatic entity state management
  • Soft Delete: Built-in soft delete with query filters
  • Design-Time Factory: Support for EF Core tools
  • Model Builder: Fluent API configuration support
  • Performance: No-tracking queries, compiled queries
  • Multiple Databases: Support for SQL Server, PostgreSQL, MySQL, SQLite, Oracle

Installation

dotnet add package Indiko.Blocks.DataAccess.EntityFramework

Quick Start

Define Your DbContext

using Indiko.Blocks.DataAccess.EntityFramework;

public class AppDbContext : BaseDbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Order> Orders { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        
        // Apply entity configurations
        modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly);
    }
}

Configure Services

public class Startup : WebStartup
{
    public override void ConfigureServices(IServiceCollection services)
    {
        base.ConfigureServices(services);
        
        services.UseEntityFrameworkDataAccess<AppDbContext>(options =>
        {
            options.ConnectionString = Configuration.GetConnectionString("DefaultConnection");
            options.DatabaseType = DatabaseType.SqlServer;
        });
    }
}

Entity Configuration

public class User : BaseEntity<Guid>
{
    public string Name { get; set; }
    public string Email { get; set; }
    public virtual ICollection<Order> Orders { get; set; }
}

public class UserConfiguration : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        builder.ToTable("Users");
        builder.HasKey(u => u.Id);
        
        builder.Property(u => u.Name)
            .IsRequired()
            .HasMaxLength(200);
            
        builder.Property(u => u.Email)
            .IsRequired()
            .HasMaxLength(256);
            
        builder.HasIndex(u => u.Email).IsUnique();
        
        builder.HasMany(u => u.Orders)
            .WithOne(o => o.User)
            .HasForeignKey(o => o.UserId);
    }
}

Usage Examples

Basic CRUD

public class UserService
{
    private readonly IRepository<User, Guid> _userRepository;
    private readonly IUnitOfWork _unitOfWork;

    public UserService(IRepository<User, Guid> userRepository, IUnitOfWork unitOfWork)
    {
        _userRepository = userRepository;
        _unitOfWork = unitOfWork;
    }

    public async Task<User> CreateAsync(string name, string email)
    {
        var user = new User { Name = name, Email = email };
        await _userRepository.AddAsync(user);
        await _unitOfWork.SaveChangesAsync();
        return user;
    }

    public async Task<User> GetByIdAsync(Guid id)
    {
        return await _userRepository.ReadByIdAsync(id);
    }

    public async Task<IEnumerable<User>> GetActiveUsersAsync()
    {
        return await _userRepository.ReadManyByQueryAsync(u => u.Status == Status.Active);
    }
}

Eager Loading

// Load user with orders
var user = await _userRepository.ReadByIdAsync(
    userId,
    asNotracking: false,
    includes: u => u.Orders
);

// Load user with nested navigation properties
var user = await _userRepository.ReadByIdAsync(
    userId,
    asNotracking: true,
    includes: new Expression<Func<User, object>>[] 
    {
        u => u.Orders,
        u => u.Orders.Select(o => o.Items)
    }
);

// Using string-based includes
var users = await _userRepository.ReadManyByQueryWithIncludesAsync(
    where: u => u.IsActive,
    asNotracking: true,
    includes: "Orders", "Orders.Items", "Profile"
);

Queries with Projections

// Select specific properties
var userDtos = await _userRepository.ReadByQueryWithSelectorAsync(
    where: u => u.IsActive,
    selector: u => new UserDto
    {
        Id = u.Id,
        Name = u.Name,
        Email = u.Email,
        OrderCount = u.Orders.Count
    }
);

// Paged projection
var pagedUserNames = await _userRepository.ReadByQueryWithSelectorPagedAsync(
    where: u => u.IsActive,
    selector: u => u.Name,
    page: 1,
    pageSize: 50
);

Transactions

public async Task ProcessOrderAsync(Order order)
{
    await _unitOfWork.BeginTransactionAsync();
    
    try
    {
        var orderRepo = _manager.GetRepository<Order, Guid>();
        var inventoryRepo = _manager.GetRepository<InventoryItem, Guid>();
        
        // Add order
        await orderRepo.AddAsync(order);
        
        // Update inventory
        foreach (var item in order.Items)
        {
            var inventoryItem = await inventoryRepo.ReadByIdAsync(item.ProductId);
            inventoryItem.Quantity -= item.Quantity;
            await inventoryRepo.UpdateAsync(inventoryItem);
        }
        
        await _unitOfWork.SaveChangesAsync();
        await _unitOfWork.CommitTransactionAsync();
    }
    catch
    {
        await _unitOfWork.RollbackTransactionAsync();
        throw;
    }
}

Configuration Options

appsettings.json

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=localhost;Database=MyApp;Trusted_Connection=True;"
  },
  "DataAccess": {
    "DatabaseType": "SqlServer",
    "EnableSensitiveDataLogging": false,
    "CommandTimeout": 30,
    "MaxRetryCount": 3,
    "EnableDetailedErrors": false
  }
}

Code Configuration

services.UseEntityFrameworkDataAccess<AppDbContext>(options =>
{
    options.ConnectionString = Configuration.GetConnectionString("DefaultConnection");
    options.DatabaseType = DatabaseType.SqlServer;
    options.EnableSensitiveDataLogging = env.IsDevelopment();
    options.CommandTimeout = 60;
});

Migrations

Create Migration

dotnet ef migrations add InitialCreate --context AppDbContext

Apply Migration

dotnet ef database update --context AppDbContext

Generate SQL Script

dotnet ef migrations script --context AppDbContext --output migration.sql

Design-Time DbContext Factory

public class AppDbContextFactory : BaseDbContextDesignTimeFactory<AppDbContext>
{
    protected override AppDbContext CreateDbContext(DbContextOptions<AppDbContext> options)
    {
        return new AppDbContext(options);
    }
}

Soft Delete

Entities inheriting from BaseEntity support soft delete:

// Soft delete (sets Status = Deleted)
await _userRepository.DeleteAsync(userId, useSoftDelete: true);

// Hard delete (removes from database)
await _userRepository.DeleteAsync(userId, useSoftDelete: false);

// Query filters automatically exclude soft-deleted entities
var activeUsers = await _userRepository.ReadAllAsync(); // Excludes deleted

Performance Tips

No-Tracking Queries

// For read-only scenarios
var users = await _userRepository.ReadManyByQueryAsync(
    where: u => u.IsActive,
    asNotracking: true  // Faster, no change tracking overhead
);

AsQueryable for Complex Queries

var query = _userRepository.AsQueryable()
    .Where(u => u.IsActive)
    .Include(u => u.Orders)
    .ThenInclude(o => o.Items)
    .OrderByDescending(u => u.CreatedAt)
    .Take(10);

var users = await query.ToListAsync();

Batch Operations

// More efficient than individual operations
await _userRepository.AddRangeAsync(users);
await _unitOfWork.SaveChangesAsync();

Supported Databases

  • SQL Server (2012+)
  • PostgreSQL (10+)
  • MySQL (5.7+)
  • SQLite (3.7+)
  • Oracle (11g+)
  • MariaDB (10.2+)

Target Framework

  • .NET 10

Dependencies

  • Indiko.Blocks.DataAccess.Abstractions
  • Microsoft.EntityFrameworkCore (9.0+)
  • Microsoft.EntityFrameworkCore.Relational

License

See LICENSE file in the repository root.

  • Indiko.Blocks.DataAccess.Abstractions - Core data access abstractions
  • Indiko.Blocks.DataAccess.MongoDb - MongoDB implementation
  • Indiko.Blocks.DataAccess.Marten - Event sourcing with Marten
  • Microsoft.EntityFrameworkCore.SqlServer - SQL Server provider
  • Npgsql.EntityFrameworkCore.PostgreSQL - PostgreSQL provider
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
2.1.1 42 12/2/2025
2.1.0 35 12/2/2025
2.0.0 267 9/17/2025
1.7.23 330 9/8/2025
1.7.22 171 9/8/2025
1.7.21 184 8/14/2025
1.7.20 209 6/23/2025
1.7.19 174 6/3/2025
1.7.18 181 5/29/2025
1.7.17 172 5/26/2025
1.7.15 128 4/12/2025
1.7.14 154 4/11/2025
1.7.13 146 3/29/2025
1.7.12 149 3/28/2025
1.7.11 159 3/28/2025
1.7.10 161 3/28/2025
1.7.9 157 3/28/2025
1.7.8 161 3/28/2025
1.7.5 183 3/17/2025
1.7.4 162 3/16/2025
1.7.3 170 3/16/2025
1.7.2 163 3/16/2025
1.7.1 197 3/11/2025
1.6.8 193 3/11/2025
1.6.7 247 3/4/2025
1.6.6 152 2/26/2025
1.6.5 151 2/20/2025
1.6.4 130 2/20/2025
1.6.3 144 2/5/2025
1.6.2 141 1/24/2025
1.6.1 130 1/24/2025
1.6.0 125 1/16/2025
1.5.2 117 1/16/2025
1.5.1 171 11/3/2024
1.5.0 145 10/26/2024
1.3.2 145 10/24/2024
1.3.0 144 10/10/2024
1.2.5 149 10/9/2024
1.2.4 141 10/8/2024
1.2.1 142 10/3/2024
1.2.0 136 9/29/2024
1.1.1 152 9/23/2024
1.1.0 162 9/18/2024
1.0.33 170 9/15/2024
1.0.28 144 8/28/2024
1.0.27 174 8/24/2024
1.0.26 200 7/7/2024
1.0.25 165 7/6/2024
1.0.24 150 6/25/2024
1.0.23 165 6/1/2024
1.0.22 138 5/14/2024
1.0.21 122 5/14/2024
1.0.20 117 4/8/2024
1.0.19 103 4/3/2024
1.0.18 108 3/23/2024
1.0.17 109 3/19/2024
1.0.16 106 3/19/2024
1.0.15 106 3/11/2024
1.0.14 109 3/10/2024
1.0.13 115 3/6/2024
1.0.12 128 3/1/2024
1.0.11 107 3/1/2024
1.0.10 120 3/1/2024
1.0.9 104 3/1/2024
1.0.8 106 2/19/2024
1.0.7 107 2/17/2024
1.0.6 101 2/17/2024
1.0.5 103 2/17/2024
1.0.4 119 2/7/2024
1.0.3 105 2/6/2024
1.0.1 92 2/6/2024
1.0.0 161 1/9/2024
1.0.0-preview99 134 12/22/2023
1.0.0-preview98 100 12/21/2023
1.0.0-preview97 101 12/21/2023
1.0.0-preview96 106 12/20/2023
1.0.0-preview94 88 12/18/2023
1.0.0-preview93 228 12/13/2023
1.0.0-preview92 90 12/13/2023
1.0.0-preview91 123 12/12/2023
1.0.0-preview90 92 12/11/2023
1.0.0-preview89 86 12/11/2023
1.0.0-preview88 168 12/6/2023
1.0.0-preview87 106 12/6/2023
1.0.0-preview86 103 12/6/2023
1.0.0-preview85 107 12/6/2023
1.0.0-preview84 95 12/5/2023
1.0.0-preview83 115 12/5/2023
1.0.0-preview82 100 12/5/2023
1.0.0-preview81 105 12/4/2023
1.0.0-preview80 98 12/1/2023
1.0.0-preview77 97 12/1/2023
1.0.0-preview76 89 12/1/2023
1.0.0-preview75 132 12/1/2023
1.0.0-preview74 153 11/26/2023
1.0.0-preview73 136 11/7/2023
1.0.0-preview72 136 11/6/2023
1.0.0-preview71 133 11/3/2023
1.0.0-preview70 146 11/2/2023
1.0.0-preview69 141 11/2/2023
1.0.0-preview68 116 11/2/2023
1.0.0-preview67 137 11/2/2023
1.0.0-preview66 103 11/2/2023
1.0.0-preview65 135 11/2/2023
1.0.0-preview64 131 11/2/2023
1.0.0-preview63 141 11/2/2023
1.0.0-preview62 142 11/1/2023
1.0.0-preview61 130 11/1/2023
1.0.0-preview60 144 11/1/2023
1.0.0-preview59 136 11/1/2023
1.0.0-preview58 140 10/31/2023
1.0.0-preview57 139 10/31/2023
1.0.0-preview56 134 10/31/2023
1.0.0-preview55 137 10/31/2023
1.0.0-preview54 129 10/31/2023
1.0.0-preview53 117 10/31/2023
1.0.0-preview52 129 10/31/2023
1.0.0-preview51 129 10/31/2023
1.0.0-preview50 124 10/31/2023
1.0.0-preview48 129 10/31/2023
1.0.0-preview46 130 10/31/2023
1.0.0-preview45 134 10/31/2023
1.0.0-preview44 135 10/31/2023
1.0.0-preview43 127 10/31/2023
1.0.0-preview42 121 10/30/2023
1.0.0-preview41 129 10/30/2023
1.0.0-preview40 136 10/27/2023
1.0.0-preview39 136 10/27/2023
1.0.0-preview38 134 10/27/2023
1.0.0-preview37 132 10/27/2023
1.0.0-preview36 120 10/27/2023
1.0.0-preview35 126 10/27/2023
1.0.0-preview34 115 10/27/2023
1.0.0-preview33 138 10/26/2023
1.0.0-preview32 119 10/26/2023
1.0.0-preview31 138 10/26/2023
1.0.0-preview30 138 10/26/2023
1.0.0-preview29 142 10/26/2023
1.0.0-preview28 137 10/26/2023
1.0.0-preview27 143 10/26/2023
1.0.0-preview26 148 10/25/2023
1.0.0-preview25 133 10/23/2023
1.0.0-preview24 119 10/23/2023
1.0.0-preview23 143 10/23/2023
1.0.0-preview22 127 10/23/2023
1.0.0-preview21 137 10/23/2023
1.0.0-preview20 134 10/20/2023
1.0.0-preview19 130 10/19/2023
1.0.0-preview18 141 10/18/2023
1.0.0-preview16 124 10/11/2023
1.0.0-preview14 141 10/10/2023
1.0.0-preview13 137 10/10/2023
1.0.0-preview12 134 10/9/2023
1.0.0-preview11 131 10/9/2023
1.0.0-preview101 90 1/5/2024