Dapper is the relational “micro-ORM” option in FlexBase: explicit SQL, minimal overhead, and high performance.
Flex wraps Dapper with Flex Dapper (a Dapper-first implementation of the Flex MicroORM abstraction). Your application code can stay provider-agnostic by using:
IFlexDapperRepository for query/command helpers
FlexDapperSql + ProviderSqlMap for provider-specific SQL variants
using Sumeru.Flex;
public sealed class ListActiveUsers
{
private readonly IFlexDapperRepository _db;
public ListActiveUsers(IFlexDapperRepository db) => _db = db;
public Task<IReadOnlyList<UserListItemDto>> FetchAsync()
{
FlexDapperSql sql = "SELECT Id, UserName FROM Users WHERE IsActive = 1 ORDER BY UserName";
return _db.QueryAsync<UserListItemDto>(sql);
}
}
public sealed class UserListItemDto
{
public string Id { get; set; }
public string UserName { get; set; }
}
using Sumeru.Flex;
public sealed class CreateUserHandler
{
private readonly IFlexDapperRepository _db;
public CreateUserHandler(IFlexDapperRepository db) => _db = db;
public Task<int?> ExecuteAsync(CreateUserCommand cmd)
{
FlexDapperSql sql = """
INSERT INTO Users (UserName, Email, IsActive)
VALUES (@UserName, @Email, 1);
SELECT CAST(SCOPE_IDENTITY() as int);
""";
return _db.ExecuteScalarAsync<int>(sql, new { cmd.UserName, cmd.Email });
}
}
public sealed record CreateUserCommand(string UserName, string Email);
using Sumeru.Flex;
public sealed class ListRecentAccounts
{
private readonly IFlexDapperRepository _db;
public ListRecentAccounts(IFlexDapperRepository db) => _db = db;
public Task<IReadOnlyList<Accountability>> FetchAsync(int take)
{
var sql = FlexDapperSql.FromProviderMap(
ProviderSqlMap.Create(map =>
map.ForSqlServer($"SELECT TOP {take} * FROM Accountabilities ORDER BY CreatedDate DESC")
.ForPostgres($"SELECT * FROM \"Accountabilities\" ORDER BY \"CreatedDate\" DESC LIMIT {take}")));
return _db.QueryAsync<Accountability>(sql);
}
}
public sealed class GetUsersPaged
{
private readonly IFlexDapperRepository _db;
public GetUsersPaged(IFlexDapperRepository db) => _db = db;
public Task<FlexDapperPagedResult<User>> FetchAsync(int pageNumber, int pageSize)
{
var query = new FlexDapperPagedQuery(
dataSql: "SELECT * FROM Users ORDER BY Id OFFSET @Offset ROWS FETCH NEXT @PageSize ROWS ONLY",
countSql: "SELECT COUNT(1) FROM Users",
pageNumber: pageNumber,
pageSize: pageSize);
return _db.QueryPageAsync<User>(query);
}
}