Preview Support for Vertica is Now Available in RepoDB

5 minute read

Published:

We are excited to announce the preview release of Vertica support for RepoDB — bringing our hybrid ORM’s fluent CRUD, raw-SQL, and Bulk Operations capabilities to Vertica for the first time, right out of the gate.

What’s in this preview?

The new RepoDb.Vertica package brings the full RepoDB experience to Vertica:

It follows the same programming model you already use with our SQL Server, PostgreSQL, MySQL, SQLite, Oracle, DB2, MariaDB, Firebird, and ClickHouse extensions — the same fluent API, the same lightweight philosophy, now targeting Vertica.

Why Vertica?

Vertica is a mature, MPP columnar database built for large-scale analytics and data-warehousing workloads — the kind of enterprise deployment where a lightweight, ADO.NET-native data-access layer is often missing. It’s also been a recurring request from the community. This preview closes that gap, so teams running on Vertica can get the same fast, hybrid data-access experience RepoDB is known for on other providers.

Vertica has a few quirks of its own — worth knowing up front

Vertica’s ADO.NET driver (Vertica.Data) and SQL dialect come with a handful of behaviors RepoDB has had to design around explicitly:

  • UseVertica() forces invariant culture, process-wide. Calling GlobalConfiguration.Setup().UseVertica() sets CultureInfo.CurrentCulture to CultureInfo.InvariantCulture for the whole process — a deliberate workaround for date corruption in the Vertica.Data driver, not an accidental side effect. Know this before wiring it into an app that relies on a different culture elsewhere.
  • Integer columns map to long. Vertica treats SMALLINT, INTEGER, and BIGINT identically under the hood, so map all of them to long in your entities rather than int or short.
  • Merge compiles to UPDATE + INSERT WHERE NOT EXISTS. Vertica has no direct MERGE-against-identity-column support, so Merge issues an UPDATE followed by an INSERT ... WHERE NOT EXISTS, joined into a single command — and when an identity column is involved, RepoDB falls back to a procedural approach rather than a plain MERGE statement, since Vertica rejects that combination outright.
  • Table hints aren’t supported. Passing hints to an operation throws a NotSupportedException — there’s no Vertica equivalent to translate them to.
  • Batch operations aren’t uniformly batched. InsertAll batches rows into multi-row VALUES statements as you’d expect, but MergeAll and UpdateAll require batchSize: 1 — passing anything higher throws a NotSupportedException. Reach for BulkMerge/BulkUpdate instead if you need real throughput on those.

None of this is a RepoDB shortcoming — it’s Vertica’s own driver and SQL-dialect behavior, and the provider is built to work within those constraints rather than silently mask them.

Getting started

Install the packages:

> Install-Package RepoDb.Vertica -Version 0.0.1-alpha1
> Install-Package RepoDb.Vertica.BulkOperations -Version 0.0.1-alpha1

Initialize it once at startup:

GlobalConfiguration
    .Setup()
    .UseVertica();

Basic CRUD

using (var connection = new VerticaConnection(connectionString))
{
    // Insert
    var person = new Person { Name = "John Doe", Age = 30, CreatedDateUtc = DateTime.UtcNow };
    var id = connection.Insert(person);

    // Query
    var queriedPerson = connection.Query<Person>(e => e.Id == id).FirstOrDefault();

    // Update
    queriedPerson.Age = 31;
    var updatedRows = connection.Update(queriedPerson);

    // Delete
    var deletedRows = connection.Delete<Person>(id);

    // Merge
    var mergedPerson = new Person { Id = id, Name = "John Doe", Age = 32, CreatedDateUtc = DateTime.UtcNow };
    var mergeResult = connection.Merge(mergedPerson);
}

Person.Id, Person.Age, and any other integer-typed column above are declared as long — Vertica doesn’t distinguish SMALLINT/INTEGER/BIGINT at the ADO.NET level.

Raw-SQL

using (var connection = new VerticaConnection(connectionString))
{
    var people = connection.ExecuteQuery<Person>("SELECT * FROM \"Person\" ORDER BY \"Id\" ASC;");

    var affectedRows = connection.ExecuteNonQuery("DELETE FROM \"Person\" WHERE \"Id\" = @Id;",
        new { Id = 10045 });

    var maxId = connection.ExecuteScalar<long>("SELECT MAX(\"Id\") FROM \"Person\";");
}

Bulk Operations

using (var connection = new VerticaConnection(connectionString))
{
    // BulkInsert — streamed through VerticaCopyStream
    var people = GetPeopleToInsert();
    var insertedRows = connection.BulkInsert(people);

    // BulkMerge
    var peopleToMerge = GetPeopleToMerge();
    var mergedRows = connection.BulkMerge(peopleToMerge, qualifiers: e => e.Id);

    // BulkDeleteByKey
    var keysToDelete = new long[] { 10045, 10046, 10047 };
    var deletedByKeyRows = connection.BulkDeleteByKey<Person>(keysToDelete);
}

A preview, not a final release

As a preview package at v0.0.1-alpha1, RepoDb.Vertica (and its Bulk Operations counterpart) is still maturing — APIs and behavior, including the caveats described above, may change before a stable release ships. We would love to hear your feedback as you try it out; it directly shapes what we prioritize on the way to general availability.


~ Conceptualized by me. Reviewed and checked by AI. Refined and gatekept by me. ~

Please support us

Give a ⭐ to our Github repository | Follow me at X / Twitter | Connect with us at our official Teams Channel
Apache License 2.0 — Copyright © 2026 by Michael Camara Pendon / Create a Request