Indiko.Blocks.DataAccess.EntityFramework 2.1.2

dotnet add package Indiko.Blocks.DataAccess.EntityFramework --version 2.1.2
                    
NuGet\Install-Package Indiko.Blocks.DataAccess.EntityFramework -Version 2.1.2
                    
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.2" />
                    
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.2" />
                    
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.2
                    
#r "nuget: Indiko.Blocks.DataAccess.EntityFramework, 2.1.2"
                    
#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.2
                    
#: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.2
                    
Install as a Cake Addin
#tool nuget:?package=Indiko.Blocks.DataAccess.EntityFramework&version=2.1.2
                    
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.2 233 12/18/2025
2.1.1 636 12/2/2025
2.1.0 615 12/2/2025
2.0.0 274 9/17/2025
1.7.23 334 9/8/2025
1.7.22 180 9/8/2025
1.7.21 194 8/14/2025
1.7.20 222 6/23/2025
1.7.19 184 6/3/2025
1.7.18 188 5/29/2025
1.7.17 179 5/26/2025
1.7.15 132 4/12/2025
1.7.14 161 4/11/2025
1.7.13 149 3/29/2025
1.7.12 152 3/28/2025
1.7.11 164 3/28/2025
1.7.10 167 3/28/2025
1.7.9 162 3/28/2025
1.7.8 166 3/28/2025
1.7.5 191 3/17/2025
1.7.4 171 3/16/2025
1.7.3 175 3/16/2025
1.7.2 171 3/16/2025
1.7.1 204 3/11/2025
1.6.8 202 3/11/2025
1.6.7 254 3/4/2025
1.6.6 158 2/26/2025
1.6.5 159 2/20/2025
1.6.4 139 2/20/2025
1.6.3 153 2/5/2025
1.6.2 148 1/24/2025
1.6.1 135 1/24/2025
1.6.0 133 1/16/2025
1.5.2 122 1/16/2025
1.5.1 173 11/3/2024
1.5.0 148 10/26/2024
1.3.2 148 10/24/2024
1.3.0 152 10/10/2024
1.2.5 153 10/9/2024
1.2.4 150 10/8/2024
1.2.1 145 10/3/2024
1.2.0 141 9/29/2024
1.1.1 160 9/23/2024
1.1.0 165 9/18/2024
1.0.33 172 9/15/2024
1.0.28 148 8/28/2024
1.0.27 176 8/24/2024
1.0.26 205 7/7/2024
1.0.25 170 7/6/2024
1.0.24 155 6/25/2024
1.0.23 168 6/1/2024
1.0.22 144 5/14/2024
1.0.21 128 5/14/2024
1.0.20 120 4/8/2024
1.0.19 109 4/3/2024
1.0.18 111 3/23/2024
1.0.17 115 3/19/2024
1.0.16 110 3/19/2024
1.0.15 109 3/11/2024
1.0.14 116 3/10/2024
1.0.13 122 3/6/2024
1.0.12 133 3/1/2024
1.0.11 116 3/1/2024
1.0.10 126 3/1/2024
1.0.9 113 3/1/2024
1.0.8 114 2/19/2024
1.0.7 113 2/17/2024
1.0.6 108 2/17/2024
1.0.5 110 2/17/2024
1.0.4 124 2/7/2024
1.0.3 112 2/6/2024
1.0.1 96 2/6/2024
1.0.0 166 1/9/2024
1.0.0-preview99 141 12/22/2023
1.0.0-preview98 107 12/21/2023
1.0.0-preview97 107 12/21/2023
1.0.0-preview96 110 12/20/2023
1.0.0-preview94 92 12/18/2023
1.0.0-preview93 231 12/13/2023
1.0.0-preview92 98 12/13/2023
1.0.0-preview91 127 12/12/2023
1.0.0-preview90 96 12/11/2023
1.0.0-preview89 89 12/11/2023
1.0.0-preview88 171 12/6/2023
1.0.0-preview87 111 12/6/2023
1.0.0-preview86 113 12/6/2023
1.0.0-preview85 115 12/6/2023
1.0.0-preview84 100 12/5/2023
1.0.0-preview83 124 12/5/2023
1.0.0-preview82 105 12/5/2023
1.0.0-preview81 114 12/4/2023
1.0.0-preview80 103 12/1/2023
1.0.0-preview77 100 12/1/2023
1.0.0-preview76 92 12/1/2023
1.0.0-preview75 138 12/1/2023
1.0.0-preview74 157 11/26/2023
1.0.0-preview73 141 11/7/2023
1.0.0-preview72 140 11/6/2023
1.0.0-preview71 136 11/3/2023
1.0.0-preview70 149 11/2/2023
1.0.0-preview69 144 11/2/2023
1.0.0-preview68 118 11/2/2023
1.0.0-preview67 144 11/2/2023
1.0.0-preview66 106 11/2/2023
1.0.0-preview65 138 11/2/2023
1.0.0-preview64 133 11/2/2023
1.0.0-preview63 149 11/2/2023
1.0.0-preview62 145 11/1/2023
1.0.0-preview61 134 11/1/2023
1.0.0-preview60 150 11/1/2023
1.0.0-preview59 138 11/1/2023
1.0.0-preview58 146 10/31/2023
1.0.0-preview57 142 10/31/2023
1.0.0-preview56 138 10/31/2023
1.0.0-preview55 141 10/31/2023
1.0.0-preview54 133 10/31/2023
1.0.0-preview53 121 10/31/2023
1.0.0-preview52 138 10/31/2023
1.0.0-preview51 133 10/31/2023
1.0.0-preview50 128 10/31/2023
1.0.0-preview48 130 10/31/2023
1.0.0-preview46 137 10/31/2023
1.0.0-preview45 141 10/31/2023
1.0.0-preview44 140 10/31/2023
1.0.0-preview43 132 10/31/2023
1.0.0-preview42 124 10/30/2023
1.0.0-preview41 132 10/30/2023
1.0.0-preview40 139 10/27/2023
1.0.0-preview39 141 10/27/2023
1.0.0-preview38 140 10/27/2023
1.0.0-preview37 133 10/27/2023
1.0.0-preview36 124 10/27/2023
1.0.0-preview35 128 10/27/2023
1.0.0-preview34 118 10/27/2023
1.0.0-preview33 142 10/26/2023
1.0.0-preview32 124 10/26/2023
1.0.0-preview31 141 10/26/2023
1.0.0-preview30 141 10/26/2023
1.0.0-preview29 148 10/26/2023
1.0.0-preview28 141 10/26/2023
1.0.0-preview27 146 10/26/2023
1.0.0-preview26 154 10/25/2023
1.0.0-preview25 138 10/23/2023
1.0.0-preview24 124 10/23/2023
1.0.0-preview23 146 10/23/2023
1.0.0-preview22 132 10/23/2023
1.0.0-preview21 141 10/23/2023
1.0.0-preview20 138 10/20/2023
1.0.0-preview19 137 10/19/2023
1.0.0-preview18 144 10/18/2023
1.0.0-preview16 128 10/11/2023
1.0.0-preview14 145 10/10/2023
1.0.0-preview13 139 10/10/2023
1.0.0-preview12 141 10/9/2023
1.0.0-preview11 134 10/9/2023
1.0.0-preview101 98 1/5/2024