Dapper works today
The first live consumer of the provider, and the gate that keeps it honest: Dapper talks to IDbConnection and nothing else, so a flow that works here works for any caller shaped the same way. This is the provider's gate test, not an example invented for the docs.
using H2Sharp.Data;
using IDbConnection con = new H2Connection("jdbc:h2:mem:demo");
con.Open();
_ = con.Execute("DROP TABLE IF EXISTS PERSON");
_ = con.Execute("CREATE TABLE PERSON(ID INT PRIMARY KEY, NAME VARCHAR(100) NOT NULL, AGE INT)");
int inserted = con.Execute(
"INSERT INTO PERSON(ID, NAME, AGE) VALUES (@Id, @Name, @Age)",
new Person { Id = 1, Name = "Ada", Age = 36 });
var rows = con.Query<Person>("SELECT ID, NAME, AGE FROM PERSON ORDER BY ID").AsList();
int updated = con.Execute(
"UPDATE PERSON SET AGE = @Age WHERE ID = @Id", new { Id = 1, Age = 37 });
int count = con.QuerySingle<int>("SELECT COUNT(*) FROM PERSON");
con.Execute("DELETE FROM PERSON WHERE ID = @Id", new { Id = 1 });
Dapper's own IDbTransaction support works too — BeginTransaction hands out a real transaction over the engine's own one.
Why this test and not another
- Read after write. The select is repeated after the update — an update that reports one row and leaves the old value behind is exactly the bug a smoke test exists to catch, and a single select would miss it.
- Scalar is a separate path. Dapper's single-value path differs from materialisation; a provider that answers the first and not the second is common, so both are exercised.
- H2 spelling on purpose. The flow uses
jdbc:h2:mem:…rather thanData Source=…— that is the form that needs parsing. AData Sourcetest would pass on a provider that took the text and looked at none of it. - Not written against its own members. Nothing here touches
H2Connectionbeyond handing it to Dapper.
Async (OpenAsync, ExecuteAsync, QueryAsync) is available on the provider; the gate test drives the synchronous surface.