RepositoryBase - lobodava/artisan-orm GitHub Wiki

RepositoryBase is the base class for your custom repository classes. It owns a single SqlConnection (created in the constructor and disposed when the repository is disposed) plus an optional ambient SqlTransaction that gets attached to every command issued by inherited methods.

public class UserRepository : RepositoryBase
{
    public UserRepository(string connectionString) : base(connectionString) { }
}

What it gives you

  • Connection management — the underlying SqlConnection is created closed and opened on demand by individual Read* / Execute* methods, then closed back. The connection is reused across calls and disposed when the repository is disposed.

  • Three SqlCommand initialization entry pointsGetByCommand, RunCommand, ExecuteCommand. See SqlCommand initialization for the differences.

  • Read shortcutsReadTo<T>, ReadToList<T>, ReadAs<T>, ReadToArray<T>, ReadToDictionary<TKey,TValue>, ReadToTree<T>, ReadToObjectRows<T>, and the multi-result-set ReadToLists<T1, T2[, T3[, T4]]>. All of them have async siblings and most accept either params SqlParameter[] or Action<SqlCommand> for parameter setup. See Read methods.

  • Write shortcutsExecute(...) / ExecuteAsync(...) for stored procedures or text batches with optional return value, plus BulkCopy<T> / BulkCopyAs<T> for high-throughput inserts.

  • Transactions — both manual-commit (BeginTransaction) and auto-commit (RunInTransaction), each with isolation-level overloads and async variants. See Transactions.

Lifetime

A repository instance owns one SqlConnection and a mutable Transaction field, so it is not safe to share across concurrent operations. Treat one repository as one unit of work:

  • ASP.NET Core / DI containers — register as Scoped and inject. The container disposes the repository at the end of the HTTP request automatically. See Using Artisan.Orm in ASP.NET Core.

  • Console apps and scriptsusing var repo = new UserRepository(connStr);.

  • Background workers without a DI scopeusing var scope = _scopeFactory.CreateScope(); var repo = scope.ServiceProvider.GetRequiredService<MyRepo>();.

Constructors

public RepositoryBase(string connectionString);
public RepositoryBase(SqlTransaction? transaction, string connectionString);

The second overload lets you attach an existing transaction — useful when wiring multiple repositories into the same logical unit of work.

Public surface

public class RepositoryBase : IDisposable, IAsyncDisposable
{
    public SqlConnection?   Connection      { get; }   // nullable, disposed-aware
    public string           ConnectionString { get; }
    public SqlTransaction?  Transaction     { get; set; }

    // SqlCommand initialization
    public T          GetByCommand<T>(Func<SqlCommand, T> func);
    public Task<T>    GetByCommandAsync<T>(Func<SqlCommand, Task<T>> funcAsync);
    public void       RunCommand(Action<SqlCommand> action);
    public int        ExecuteCommand(Action<SqlCommand> action);
    // ... + Async / CancellationToken variants

    // Read families
    public T?            ReadTo<T>      (string sql, params SqlParameter[] sqlParameters);
    public IList<T>      ReadToList<T>  (string sql, params SqlParameter[] sqlParameters);
    public T[]           ReadToArray<T> (string sql, params SqlParameter[] sqlParameters);
    public ObjectRows    ReadToObjectRows<T>(...);
    public IDictionary<TKey, TValue> ReadToDictionary<TKey, TValue>(...);
    public T?            ReadToTree<T>(...) where T : class, INode<T>;
    public (IList<T1>, IList<T2>) ReadToLists<T1, T2>(...);
    // ... + ReadAs* (auto-mapping) siblings, all with Async variants

    // Write
    public int           Execute(string sql, params SqlParameter[] sqlParameters);
    public int           BulkCopy<T>     (IEnumerable<T> rows, string destinationTable, ...);
    public int           BulkCopyAs<T>   (IEnumerable<T> rows, string destinationTable, ...);

    // Transactions
    public void          BeginTransaction(Action<SqlTransaction> action);
    public void          RunInTransaction(Action<SqlTransaction> action);
    // ... + IsolationLevel and Async overloads
}

See also:

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