Aumerial.EntityFrameworkCore
10.5.0
dotnet add package Aumerial.EntityFrameworkCore --version 10.5.0
NuGet\Install-Package Aumerial.EntityFrameworkCore -Version 10.5.0
<PackageReference Include="Aumerial.EntityFrameworkCore" Version="10.5.0" />
<PackageVersion Include="Aumerial.EntityFrameworkCore" Version="10.5.0" />
<PackageReference Include="Aumerial.EntityFrameworkCore" />
paket add Aumerial.EntityFrameworkCore --version 10.5.0
#r "nuget: Aumerial.EntityFrameworkCore, 10.5.0"
#:package Aumerial.EntityFrameworkCore@10.5.0
#addin nuget:?package=Aumerial.EntityFrameworkCore&version=10.5.0
#tool nuget:?package=Aumerial.EntityFrameworkCore&version=10.5.0
NTi Entity Framework Core Provider
Entity Framework Core provider for IBM i, iSeries and AS/400 servers, built on the NTi Data Provider: fully managed, no ODBC driver, no IBM i Access installation, no unmanaged dependency. Bring LINQ, migrations and reverse engineering to DB2 for i.
The version rule is simple: the major tracks the Entity Framework Core major (8.x for EF Core 8, 9.x for EF Core 9, 10.x for EF Core 10) and the minor tracks the NTi engine generation (x.5 runs on NTi 5).
Info
Contact us
Documentation
2026 - AUMERIAL SAS
Getting started
using Microsoft.EntityFrameworkCore;
public class OrderContext : DbContext
{
public DbSet<Order> Orders => Set<Order>();
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseNTi("server=MYIBMI;user=MYUSER;password=MYPASSWORD;database=MYLIB;");
}
public class Order
{
public int Id { get; set; } // IDENTITY column, value returned on insert
public string Customer { get; set; } = "";
public decimal Amount { get; set; }
public DateTime PlacedOn { get; set; }
}
The connection string uses the same keywords as the NTi ADO.NET provider; database
selects the target schema (library). Or with dependency injection:
services.AddDbContext<OrderContext>(o => o.UseNTi(connectionString));
Then use EF Core as usual:
using var db = new OrderContext();
db.Database.Migrate(); // creates the schema (library) if needed, then applies migrations
db.Orders.Add(new Order { Customer = "ACME", Amount = 1249.90m, PlacedOn = DateTime.Now });
db.SaveChanges(); // IDENTITY value flows back through SELECT ... FROM FINAL TABLE
var top = await db.Orders
.Where(o => o.Amount > 1000m)
.OrderByDescending(o => o.Amount)
.Take(10)
.ToListAsync(); // FETCH FIRST / OFFSET pagination, DB2 for i dialect throughout
Reverse engineering an existing library works with the standard tooling, including
legacy artifacts (zoned and packed decimals, FOR BIT DATA, DECFLOAT, tables
without primary keys, views):
dotnet ef dbcontext scaffold "server=MYIBMI;user=MYUSER;password=MYPASSWORD;database=MYLIB;" Aumerial.EntityFrameworkCore
Provider options
options.UseNTi(connectionString, nti => nti
.UnicodeCcsid(1208) // CCSID for Unicode columns (default 1208 / UTF-8)
.ForceUnicode() // store all text columns as Unicode
.VarcharMaxLength(8000) // default length for VARCHAR columns without HasMaxLength
.VarbinaryMaxLength(8000) // same for VARBINARY
.VargraphicMaxLength(8000) // same for VARGRAPHIC
.DecimalDefaults(31, 8)); // precision/scale for decimals without HasPrecision
All options are optional; the defaults work against any existing schema. The
standard EF Core annotations compose with them: [Unicode] / IsUnicode() per
property, and [Column(TypeName = "NUMERIC(7,2)")] / HasColumnType(...) to pin
an exact DB2 for i store type (NUMERIC is zoned, DECIMAL is packed), which is
the key to matching physical files consumed by RPG or COBOL programs.
Opt-in model features:
propertyBuilder.UseHiLo()/modelBuilder.UseHiLo(): HiLo key generation backed by a DB2 for i sequence (NEXT VALUE FOR), block reservation, no identity round-trip per insert.propertyBuilder.IsRowChangeTimestamp(): optimistic concurrency token backed by the nativeROW CHANGE TIMESTAMPcolumn, rewritten by the server on every update (the DB2 for i analogue of SQL Server'srowversion).EF.Functionsextensions:JsonValue,JsonQuery,JsonExists,RelativeRecordNumber(RRN),RecordId(RID), standard deviation and variance aggregates.
What the provider takes care of
- Truly asynchronous execution.
ToListAsync,SaveChangesAsync,OpenAsyncand friends ride the native asynchronous engine of the NTi 5 provider: no thread is ever blocked on I/O, and cancellation tokens are honored at every phase. - Identifiers are emitted uppercase and quoted (
"ORDERS"), so EF-created objects keep their SQL name as system name and stay reachable from native tools (FROM ORDERSworks in STRSQL, DDS tooling and friends). Reserved words (ORDER,USER,GROUP) are safe. - The DB2 for i dialect end to end: no SQL boolean type (predicates and values converted
through
CASEand= 1where required),EXISTSscalarized outsideWHERE, labeled durations for date arithmetic (works on every IBM i release),FETCH FIRSTandOFFSETpagination,LISTAGG,COUNT_BIG, statistics aggregates, JSON functions. - Migrations: schema (library) creation, history table, idempotent scripts through
compound SQL PL blocks,
COMMENT ONfor table comments, sequences. - Scaffolding: tables, views, keyless tables, indexes, foreign keys, comments, sequences,
legacy column types (zoned and packed decimal,
FOR BIT DATAasbyte[],DECFLOAT).
Main limitations
- The
*SQLnaming convention is required. The provider qualifies objects asSCHEMA.TABLE; a connection string requestingnaming=*SYSis rejected at context creation with an explicit message. - Column rename is not supported by DB2 for i. The provider fails migrations with an
actionable message instead of applying a destructive workaround. The same applies to
altering the IDENTITY or
ROW CHANGE TIMESTAMPnature of an existing column. - One statement per round-trip (
MaxBatchSize = 1). For bulk changes preferExecuteUpdate/ExecuteDelete, which run as a single SQL statement. - Character conversion is strict on write. A value that cannot be represented in the
target column's CCSID is rejected with an explicit error, never silently substituted or
truncated. Columns tagged CCSID 65535 (
FOR BIT DATA) are binary (byte[]) unless the connection string assertsdefault ccsid. - After an update on a
ROW CHANGE TIMESTAMPentity, reload it before saving again from the same context (the server-generated token changes on every update).
Supported platforms
- EF Core 8 (.NET 8), EF Core 9 (.NET 9), EF Core 10 (.NET 10): pick the package major matching your EF Core version
- IBM i 7.2 and later (V7R4+ recommended)
- Requires the
Aumerial.Data.Ntiprovider, version 5.0.0 or later (installed automatically as a NuGet dependency)
Release notes
8.5.0 / 9.5.0 / 10.5.0
First release of the rewritten Entity Framework Core provider on the NTi 5 engine (major = EF Core version, minor = NTi engine generation): single shared implementation for the three EF Core majors, truly asynchronous execution end to end, uppercase-quoted naming, full DB2 for i dialect in queries and migrations, HiLo andROW CHANGE TIMESTAMPopt-ins, Unicode storage options and annotations, legacy-aware scaffolding, validated against a live IBM i server.
| 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
- Aumerial.Data.Nti (>= 5.0.0 && < 6.0.0)
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.