Doka.EntityFrameworkCore.NestedSet
10.1.0
See the version list below for details.
dotnet add package Doka.EntityFrameworkCore.NestedSet --version 10.1.0
NuGet\Install-Package Doka.EntityFrameworkCore.NestedSet -Version 10.1.0
<PackageReference Include="Doka.EntityFrameworkCore.NestedSet" Version="10.1.0" />
<PackageVersion Include="Doka.EntityFrameworkCore.NestedSet" Version="10.1.0" />
<PackageReference Include="Doka.EntityFrameworkCore.NestedSet" />
paket add Doka.EntityFrameworkCore.NestedSet --version 10.1.0
#r "nuget: Doka.EntityFrameworkCore.NestedSet, 10.1.0"
#:package Doka.EntityFrameworkCore.NestedSet@10.1.0
#addin nuget:?package=Doka.EntityFrameworkCore.NestedSet&version=10.1.0
#tool nuget:?package=Doka.EntityFrameworkCore.NestedSet&version=10.1.0
Doka.EntityFrameworkCore.NestedSet
Nested-set hierarchies for Entity Framework Core, with explicit tree identity, optional scope isolation, composable queries, and atomic structural changes.
Packages
| Package | Purpose |
|---|---|
Doka.NestedSet |
EF-independent node contracts, validated bounds, and ancestry predicates |
Doka.EntityFrameworkCore.NestedSet |
Common EF mapping, hierarchy algorithms, queries, mutations, ordering, and repair |
Doka.EntityFrameworkCore.NestedSet.MySql |
Doka integration for MySQL and MariaDB |
Doka.EntityFrameworkCore.NestedSet.Postgres |
Npgsql integration for PostgreSQL |
Doka.EntityFrameworkCore.NestedSet.Sqlite |
Microsoft SQLite integration |
Doka.EntityFrameworkCore.NestedSet.SqlServer |
Microsoft SQL Server integration |
Each adapter depends on the common EF package and its actual database provider.
The common EF package references Doka.NestedSet and EF/Relational, without a
concrete provider or SafeMigrations dependency. Common hierarchy algorithms are
shared; native SQL, model conventions, and translations belong to the adapter.
Each adapter's kernel dependency is exact because it implements a private
integration contract. Keep adapter and kernel versions aligned when updating;
the kernel's public dependency on Doka.NestedSet remains a minimum version.
The 10.x package line targets .NET 10 and EF Core 10. The stable 10.1.0 contract
changes installation and infrastructure registration from 10.0.0; existing
mapping and hierarchy APIs remain in the common package. Install one adapter,
which brings in both common packages transitively:
dotnet package add Doka.EntityFrameworkCore.NestedSet.MySql --version 10.1.0
Keep all selected adapters and the common EF package at 10.1.0.
Select the adapter matching the application's EF provider;
Postgres is the NestedSet suffix for the Npgsql PostgreSQL integration.
Identify and configure a hierarchy
Each tree has a stable TreeId and its own 1..2N bounds. An optional Scope
adds a partition, such as a tenant. Equal bounds in different trees do not
identify the same node. ParentId and Position preserve adjacency and sibling
order; Left, Right, and Depth are derived structure.
Entities may implement the optional core interfaces or use explicit mapping. The following unscoped entity needs no additional parent or tree entity:
public sealed class Folder
{
public long Id { get; private set; }
public Guid TreeId { get; private set; }
public long? ParentId { get; private set; }
public string Name { get; set; } = string.Empty;
public long Left { get; private set; }
public long Right { get; private set; }
public int Depth { get; private set; }
public long Position { get; private set; }
}
Configure it through the application's normal EF configuration:
builder.HasKey(folder => folder.Id);
builder.Property(folder => folder.Name)
.HasMaxLength(256)
.IsRequired();
builder.HasNestedSet(nestedSet => nestedSet
.HasNodeKey(folder => folder.Id)
.HasTreeId(folder => folder.TreeId)
.HasParent(folder => folder.ParentId)
.HasBounds(folder => folder.Left, folder => folder.Right)
.HasDepth(folder => folder.Depth)
.HasPosition(folder => folder.Position)
.OrderBy(folder => folder.Name)
.HasOrderMode(NestedSetOrderMode.Strict));
builder is an EntityTypeBuilder<Folder>, including one supplied to
IEntityTypeConfiguration<Folder>. HasScope(...) may be omitted completely.
When configured, select that scope through ForScope(scope) before querying
or mutating the hierarchy. Strict ordering sorts each sibling group; manual
placement requires NestedSetOrderMode.AllowManualPlacement.
Register and use the EF facade
Keep the application's normal DbContext and DbSet<Folder>. Register NestedSet
once through context options. With the Doka MySQL/MariaDB provider:
services.AddDbContext<ApplicationDbContext>(options => options
.UseMySql(connectionString, serverVersion, mysql => mysql.UseNestedSets()));
serverVersion is the Doka capability profile matching the configured server.
Use the matching .Postgres, .SqlServer, or .Sqlite package and call
UseNestedSets() inside UseNpgsql, UseSqlServer, or UseSqlite respectively.
The former DbContextOptionsBuilder.UseNestedSets() overloads are removed;
registration now identifies the adapter explicitly.
Create a root and child through the metadata-validated facade:
var folders = context.NestedSet<Folder>();
var treeId = Guid.NewGuid();
var root = new Folder { Name = "Root" };
var documents = new Folder { Name = "Documents" };
await folders.InsertRootAsync(root, treeId, cancellationToken);
await folders.InsertChildAsync(documents, root.Id, cancellationToken);
Queries resolve their anchor in SQL without requiring the caller to preload it:
var matchingNodes = await folders
.InTree(treeId)
.Nodes
.Where(folder => folder.Name.StartsWith("D"))
.ToListAsync(cancellationToken);
var ancestors = await folders
.AncestorsOf(documents.Id)
.Where(folder => folder.Name == "Root")
.ToListAsync(cancellationToken);
Queries respect EF query filters and are no-tracking by default. Whole trees
are returned in Left preorder. A global business OrderBy would reorder
different levels together; configure sibling ordering on the model instead.
Compose directions and paths
SelectSubtrees, SelectAncestors, and SelectAncestorsOrSelf project several
sources and their related nodes with mapped structural distance.
WherePathEdges requires a complete visible direct path;
WhereAnyAncestorOrSelf tests visible existence;
WhereNearestAncestorOrSelf chooses the nearest candidate before testing its
value and complete path. Rejection never falls back to a farther candidate.
These synchronous methods build ordinary deferred EF queries. Complete them
with application joins, filters, scalar aggregates, and an async terminal such
as ToListAsync(cancellationToken). They preserve Scope, TreeId, query filters,
and row multiplicity without loading anchors or a tree. Domain rules for
effective dates, metadata, roles, and reporting remain application-owned.
Writes and recovery
Use explicit facade operations for insert, move, detach, delete, bulk import,
and rebuild. DeleteAsync promotes a non-root node's children;
DeleteSubtreeAsync removes the branch. Deleted tree identities remain
tombstoned until a separately authorized purge.
Normal payload saves remain EF saves. Automatic tracked Parent or sorting-field
changes require SaveNestedSetChangesAsync around the application's base save,
or the optional NestedSetDbContext base class. The registered guard rejects
uncoordinated structural changes before writing inconsistent data. A normal
DbSet.Add is not a substitute for a hierarchy insertion operation.
Mutations use a library-owned transaction or a savepoint in an eligible caller transaction. They preserve caller commit ownership and restore tracked state after rollback. Callers must retain the context's single-operation discipline and own authorization, cancellation, and unknown-commit-outcome recovery.
Schema and diagnostics
Normal EF migrations include the typed tree registry, structural checks, and indexes derived from tree identity, bounds, adjacency, and configured ordering. SafeMigrations is an optional integration, not a prerequisite.
ValidateAsync, PlanRebuildAsync, and RebuildAsync are available from the
selected tree. Repair reconstructs derived structure from persisted adjacency;
it does not invent missing or ambiguous parents.
NestedSetException.Code exposes stable failure codes. Activities and metrics
use bounded labels and exclude node keys, Scope values, TreeIds, and entity
payloads. Applications own business audit records and context lifetime.
The packages are licensed under MIT.
| Product | Versions 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. |
-
net10.0
- Doka.NestedSet (>= 10.1.0)
- Microsoft.EntityFrameworkCore (>= 10.0.12 && < 11.0.0)
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.12 && < 11.0.0)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on Doka.EntityFrameworkCore.NestedSet:
| Package | Downloads |
|---|---|
|
Doka.EntityFrameworkCore.NestedSet.Sqlite
Nested-set hierarchy integration for the Sqlite Entity Framework Core provider. |
|
|
Doka.EntityFrameworkCore.NestedSet.MySql
Nested-set hierarchy integration for the MySql Entity Framework Core provider. |
|
|
Doka.EntityFrameworkCore.NestedSet.Postgres
Nested-set hierarchy integration for the Postgres Entity Framework Core provider. |
|
|
Doka.EntityFrameworkCore.NestedSet.SqlServer
Nested-set hierarchy integration for the SqlServer Entity Framework Core provider. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.3.0 | 77 | 11/6/2026 |
| 10.2.0 | 142 | 11/3/2026 |
| 10.1.0 | 153 | 10/30/2026 |
| 10.0.0 | 390 | 10/9/2026 |
| 10.0.0-rc.1 | 81 | 10/2/2026 |