Franz.Common.EntityFramework
3.0.0
dotnet add package Franz.Common.EntityFramework --version 3.0.0
NuGet\Install-Package Franz.Common.EntityFramework -Version 3.0.0
<PackageReference Include="Franz.Common.EntityFramework" Version="3.0.0" />
<PackageVersion Include="Franz.Common.EntityFramework" Version="3.0.0" />
<PackageReference Include="Franz.Common.EntityFramework" />
paket add Franz.Common.EntityFramework --version 3.0.0
#r "nuget: Franz.Common.EntityFramework, 3.0.0"
#:package Franz.Common.EntityFramework@3.0.0
#addin nuget:?package=Franz.Common.EntityFramework&version=3.0.0
#tool nuget:?package=Franz.Common.EntityFramework&version=3.0.0
Franz.Common.EntityFramework
EF Core persistence infrastructure for Franz entities, repositories, unit-of-work transactions, auditing, soft deletion, tenant filters, and optimistic concurrency.
Overview
The package provides the provider-neutral EF Core base context and repository infrastructure. Database connection configuration is supplied by a provider adapter such as PostgreSQL, MariaDB, Oracle, or SQL Server.
Installation
dotnet add package Franz.Common.EntityFramework
Configure a DbContext
A concrete context derives from DbContextBase and forwards the execution dependencies it uses. For multi-tenant applications, forward the tenant execution accessor and both option objects so model configuration can apply the intended isolation policy.
public sealed class ApplicationDbContext(
DbContextOptions<ApplicationDbContext> options,
IDispatcher dispatcher,
ITenantExecutionContextAccessor tenantContext,
IOptions<DatabaseOptions> databaseOptions,
IOptions<MultiTenancyOptions> multiTenancyOptions)
: DbContextBase(
options,
dispatcher,
tenantContextAccessor: tenantContext,
databaseOptions: databaseOptions,
multiTenancyOptions: multiTenancyOptions)
{
public DbSet<Customer> Customers => Set<Customer>();
}
For a non-multi-tenant application, the original constructor overload can be used; tenant-specific option forwarding is not required.
Register provider and repositories
Example with PostgreSQL:
using Franz.Common.EntityFramework.Extensions;
using Franz.Common.EntityFramework.Postgres.Extensions;
builder.Services
.AddPostgresDatabase<ApplicationDbContext>(builder.Configuration)
.AddEntityRepositories<ApplicationDbContext>()
.AddUnitOfWork<ApplicationDbContext>();
Provider adapters share DatabaseOptions and DatabaseTargetResolver; each adapter constructs its own provider connection configuration. See the provider package guide for the correct extension method and configuration.
Repository behavior
AddEntityRepositories<TDbContext>() discovers EF DbSet<TEntity> properties whose entity types implement IEntity<TKey>, excluding aggregate roots. It registers IEntityRepository<TEntity, TKey> and the EF bulk-update and bulk-delete contracts.
The standard repository CRUD methods call SaveChangesAsync. Repository discovery inspects the concrete DbContext's public DbSet<TEntity> properties at runtime and excludes aggregate roots; this registration is reflection-based and is not a Native AOT guarantee. Aggregate repositories are deliberately explicit and are registered with AddAggregateRepository<TAggregate, TEvent, TId, TRepository>(). Use an explicit IUnitOfWork transaction when multiple operations must commit atomically:
await unitOfWork.BeginAsync(cancellationToken);
try
{
await customerRepository.AddAsync(customer, cancellationToken);
await orderRepository.AddAsync(order, cancellationToken);
await unitOfWork.CommitAsync(cancellationToken);
}
catch
{
await unitOfWork.RollbackAsync(CancellationToken.None);
throw;
}
The unit of work owns the transaction it begins. It rejects an already-active DbContext transaction that it does not own. It commits or rolls back and releases its transaction; it does not create a distributed transaction across separate DbContexts or databases.
Persistence behavior
DbContextBase applies the following framework behavior during synchronous and asynchronous saves:
- Audit lifecycle updates for
IAuditableEntity. - Tenant ownership validation for
ITenantEntitywhen a validated tenant execution context is present. - Optimistic concurrency version increments for
IConcurrencyTrackedEntity. - Soft-delete handling for tracked entity deletions.
The model-finalization convention composes application query filters with the framework soft-delete predicate. Tenant filters are applied to tenant-owned entities only when multi-tenancy is explicitly enabled. In a shared database with multi-tenancy enabled, every IEntity<TKey> must implement exactly one of ITenantEntity or IGlobalEntity.
Tenant-owned writes fail closed without a validated tenant context. The framework does not infer tenant identity from raw headers or arbitrary claims.
Set-based operations
IEntityFrameworkBulkUpdateRepository<TEntity> exposes ExecuteBulkUpdateAsync; IEntityFrameworkBulkDeleteRepository<TEntity> exposes ExecuteBulkDeleteAsync. These use EF Core set-based operations and do not materialize each matching entity.
Bulk updates add framework audit metadata and increment ConcurrencyVersion for concurrency-tracked entities. For relational providers, TenantId is also configured as an EF concurrency token; the Cosmos provider retains its native _etag concurrency behavior. They reject changes to tenant identity and framework-managed lifecycle/audit fields. Bulk delete is soft-delete by default; pass hardDelete: true for physical deletion. Set-based operations bypass the normal change tracker, so test provider translation and transaction behavior for the concrete provider. Important distinction: the current tracked EntityRepository.DeleteAsync(..., hardDelete: true) and DeleteRangeAsync(..., hardDelete: true) paths call SaveChangesAsync, where DbContextBase converts deleted auditable entities back to soft-deleted modified entities. Use the bulk hard-delete operation for physical deletion until that tracked-delete interaction is corrected.
Database isolation modes
Database:IsolationMode supports:
SharedDatabase: use the configured database name unchanged.TenantDatabase: resolve the database name using the validated tenant execution context and the configured{dbName}token.DomainDatabase: explicitly resolve the database name using a validated domain context and the configured token.
Database routing is not a provisioning or migration system. The application owns tenant database provisioning, credential resolution, pool budgeting, and migration orchestration.
License
MIT. See the repository LICENSE.
| 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
- Franz.Common.Business (>= 3.0.0)
- Franz.Common.DependencyInjection (>= 3.0.0)
- Franz.Common.Errors (>= 3.0.0)
- Franz.Common.MultiTenancy (>= 3.0.0)
- Franz.Common.Reflection (>= 3.0.0)
- Microsoft.EntityFrameworkCore (>= 10.0.14)
- Microsoft.EntityFrameworkCore.Cosmos (>= 10.0.14)
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.14)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.14)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.14)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.14)
NuGet packages (9)
Showing the top 5 NuGet packages that depend on Franz.Common.EntityFramework:
| Package | Downloads |
|---|---|
|
Franz.Common.EntityFramework.SQLServer
Shared utility library for the Franz Framework. |
|
|
Franz.Common.EntityFramework.MariaDB
Shared utility library for the Franz Framework. |
|
|
Franz.Common.EntityFramework.PostGres
Shared utility library for the Franz Framework. |
|
|
Franz.Common.MongoDB
Shared utility library for the Franz Framework. |
|
|
Franz.Common.SSO
Shared utility library for the Franz Framework. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.0 | 142 | 11/10/2026 |
| 2.3.4 | 446 | 11/1/2026 |
| 2.3.3 | 405 | 10/28/2026 |
| 2.3.2 | 211 | 10/27/2026 |
| 2.3.1 | 256 | 10/26/2026 |
| 2.3.0 | 412 | 7/21/2026 |
| 2.2.19 | 233 | 7/19/2026 |
| 2.2.18 | 237 | 7/19/2026 |
| 2.2.17 | 758 | 7/12/2026 |
| 2.2.16 | 250 | 7/2/2026 |
| 2.2.15 | 262 | 6/29/2026 |
| 2.2.14 | 242 | 6/29/2026 |
| 2.2.13 | 248 | 6/29/2026 |
| 2.2.12 | 244 | 6/28/2026 |
| 2.2.11 | 233 | 6/28/2026 |
| 2.2.10 | 258 | 6/28/2026 |
| 2.2.9 | 248 | 6/28/2026 |
| 2.2.8 | 242 | 6/28/2026 |
| 2.2.7 | 249 | 6/7/2026 |
| 2.2.6 | 250 | 6/6/2026 |