Whats New in v4 - lobodava/artisan-orm GitHub Wiki

Artisan.Orm 4.0 is a multi-targeting refresh of the library. Existing 1.x / 2.x / 3.x code keeps working — most of the changes are additive — but there are two configuration changes worth knowing about up front, and a sizable list of new APIs.

Targets

  • netstandard2.1 — .NET Core 3.1 (EOL), Mono, Unity, Xamarin
  • net8.0 — .NET 6 / 7 / 8 / 9
  • net10.0 — current LTS

DateOnly / TimeOnly and System.Text.Json-based JSON parameters are gated behind #if NET6_0_OR_GREATER and only available on the net8.0 / net10.0 targets.

Configuration changes

  • The library no longer reads Web.config / App.config automatically. Pass the connection string explicitly to the RepositoryBase constructor — see About Connection Strings.

  • Nullable reference types are enabled. Public APIs that may return null now annotate it (User?, string?, etc.). Custom repositories that override or call these methods may surface CS86xx warnings until callers add ? annotations. No runtime behavior change.

New APIs

Bulk insert

SqlConnection.BulkCopy<T> / BulkCopyAs<T> and matching wrappers on RepositoryBase — sync and async, with CancellationToken. See BulkCopy.

Multi-result-set tuple reads

ReadToLists<T1, T2> / <T1, T2, T3> / <T1, T2, T3, T4> returning a typed tuple of lists from a single procedure with multiple select statements. See ReadToLists.

Pair them with MergeJoin to assemble parent / child object graphs from a single round-trip without a GroupJoin Dictionary allocation. See MergeJoin.

Streaming with IAsyncEnumerable

ReadToAsyncEnumerable<T> / ReadAsAsyncEnumerable<T> — for queries that return more rows than you want to buffer, stream them one at a time with cancellation support. See Streaming with IAsyncEnumerable.

JSON parameters (NET6+)

AddJsonParam<T>(name, value) — serialises a CLR object to JSON and binds it to an nvarchar(max) parameter for parsing on the SQL side via OPENJSON.

DateOnly / TimeOnly parameters and reads (NET6+)

  • AddDateParam(DateOnly) / AddTimeParam(TimeOnly) — both nullable variants
  • dr.GetDateOnly(...) / dr.GetTimeOnly(...) — with nullable and default-value overloads

Output parameters

Nine new typed helpers — AddBitOutputParam, AddTinyIntOutputParam, AddSmallIntOutputParam, AddIntOutputParam, AddBigIntOutputParam, AddDecimalOutputParam(name, precision, scale), AddGuidOutputParam, AddDateTime2OutputParam, AddDateTimeOffsetOutputParam. Read the values back via cmd.Parameters[name].Value after ExecuteNonQuery.

Default-value reader extensions

Eleven new Get* overloads with a defaultValue argument — GetByte(ord, default), GetInt32(ord, default), GetString(ord, default), GetDateTime(ord, default), etc. — for "if NULL, fall back to this".

Pre-populated lists

ReadToList<T>(sql, IList<T>? list, ...) and ReadAsList<T>(...) overloads — append fetched rows to an existing list instead of allocating a new one. Useful when assembling results from multiple queries into a single collection.

Async transactions

BeginTransactionAsync / RunInTransactionAsync — both with optional IsolationLevel and CancellationToken. See Transactions.

Async-symmetry methods

Async siblings added for previously sync-only APIs: ReadToTreeAsync, ReadToTreeListAsync, ReadToArrayAsync, ReadAsArrayAsync, ReadDynamicAsync, ReadDynamicListAsync, ReadDynamicArrayAsync, ReadToObjectRowAsync / ReadToObjectRowsAsync, plus ExecuteAsync(sql, CancellationToken, params) overload.

Bug fixes

  • RecordTypeMapper.CreateObject(SqlDataReader) standalone wrapper — was reading the wrong column ordinal when called outside a parent mapper context. Fixed.
  • ExecuteCommandAsync — fixed sync-over-async issue in the connection close path that could deadlock under tight ASP.NET Core thread-pool pressure.

Dependency updates

  • Microsoft.Data.SqlClient — bumped to 7.0.1
  • Microsoft.SourceLink.GitHub — bumped to 10.0.203 (deterministic builds, debug-step into source)

See also:

⚠️ **GitHub.com Fallback** ⚠️