StrongDAO 0.12.0
dotnet add package StrongDAO --version 0.12.0
NuGet\Install-Package StrongDAO -Version 0.12.0
<PackageReference Include="StrongDAO" Version="0.12.0" />
<PackageVersion Include="StrongDAO" Version="0.12.0" />
<PackageReference Include="StrongDAO" />
paket add StrongDAO --version 0.12.0
#r "nuget: StrongDAO, 0.12.0"
#:package StrongDAO@0.12.0
#addin nuget:?package=StrongDAO&version=0.12.0
#tool nuget:?package=StrongDAO&version=0.12.0
StrongDAO
StrongDAO is a performant extension library for Microsoft Access DAO that brings modern, strongly-typed querying capabilities to your Access database applications.
Why StrongDAO?
- Strong Typing: Query your Access databases with full type safety using classes, records, tuples, or scalar values - no more brittle string-based field access
- Easy Migration Path: Designed as a drop-in enhancement for existing DAO applications. Start using it alongside your current code without a complete rewrite
- Dapper-Like Experience: Familiar query patterns similar to OLEDB + Dapper, but using native DAO objects - no need to mix DAO and OLEDB in the same codebase (they don't mix well!)
- Fast Performance: Up to 9x faster than traditional
DAO.OpenRecordset. Offering performance on par with Dapper in some scenarios - Dynamic Support: Full support for dynamic queries when you need flexibility, with results castable to
IDictionary<string, object>
Installation
Install Nuget package Strong DAO
Added fonctionality
New extension methods
Database.Query<T>Database.QueryFirstOrDefault<T>QueryDef.Query<T>QueryDef.QueryFirstOrDefault<T>
Replace your OpenRecordset calls with the methods above to get a strongly typed object (or list of object) out of your queries.
And their dynamic counterpart:
Database.QueryDatabase.QueryFirstOrDefaultQueryDef.QueryQueryDef.QueryFirstOrDefault
You can directly cast the results of those queries to (IDictionary<string, object?>) if you need a more dictionary-like way of accessing the data.
New class:
StrongRecordset
With the corresponding extension methods:
Database.OpenStrongRecordsetQueryDef.OpenStrongRecordset
Designed as a drop-in replacement for the built-in Recordset class and the OpenRecordset methods. This new recordset offers the same fonctionality as the original one, but it allows caching of the DAO.Fields (caching is activated by default). This can result in a free 2x performance boost. See the performance section for more details.
Enumerable Recordset:
The StrongRecordset also includes the AsEnumerable() method which enables:
- foreach enumeration: Iterate through records using standard
foreachloops - LINQ support: Apply LINQ queries (e.g.,
Where,Select,OrderBy) directly on the recordset
Basic usage
// Example1: Replacing OpenRecordset with OpenStrongRecordset
_dbEngine = new DAO.DBEngine();
var _db = _dbEngine.CreateDatabase("test.mdb");
var rs = _db.OpenStrongRecordset("SELECT * FROM Users");
rs.Fields["Name"].Value = "StrongDAO";
// Example2: Using AsEnumerable() with LINQ
_dbEngine = new DAO.DBEngine();
var _db = _dbEngine.CreateDatabase("test.mdb");
var rs = _db.OpenStrongRecordset("SELECT * FROM Users");
var results = rs.AsEnumerable()
.Where(r => (int)r.Fields["Age"].Value > 18)
.Select(r => new {
Id = r.Fields["ID"].Value,
Name = r.Fields["Name"].Value
})
.ToList();
// Example 3: Doing strongly typed queries
// Class and record definition
public record PersonRecord(int? Id, string? PersonName, int? Age, string? Email, bool? IsActive, double? Score);
public class PersonClass
{
public int? Id { get; set; }
public string? PersonName { get; set; }
public int? Age { get; set; }
public string? Email { get; set; }
public bool? IsActive { get; set; }
public double? Score { get; set; }
}
_dbEngine = new DAO.DBEngine();
var _db = _dbEngine.CreateDatabase("test.mdb");
// Tuple
var person = _db.Query<(int? Id, string? PersonName, int? Age, string? Email, bool? IsActive, double? Score)>("SELECT * FROM BenchmarkTable");
// Scalar
var id = _db.Query<int?>("SELECT Id FROM BenchmarkTable");
// Class
var personClass = _db.Query<PersonClass>("SELECT * FROM BenchmarkTable");
// Record
var personRecord = _db.Query<PersonRecord>("SELECT * FROM BenchmarkTable");
_db.Close();
Performance
Benchmarks were conducted using BenchmarkDotNet on a AMD Ryzen 5 5600X system with .NET 10.0. All tests queried 50 rows from an Access database.
Key Highlights
- Up to 9x faster than DAO.OpenRecordset
- 2x faster when using OpenStrongRecordset instead of OpenRecordset
- Comparable to Dapper when mapping to Tuple while providing native DAO integration
Benchmark Results
| Method | Mean | Ratio | Allocated | Alloc Ratio |
|---|---|---|---|---|
| OLEDB_Dapper | 4.047 ms | 0.10 | 29.18 KB | 1.83 |
| StrongDAO_Tuple | 4.246 ms | 0.11 | 42.93 KB | 2.69 |
| DAO_GetRows | 4.612 ms | 0.12 | 21.23 KB | 1.33 |
| StrongDAO_Record | 8.372 ms | 0.22 | 47.22 KB | 2.96 |
| StrongDAO_Class | 8.443 ms | 0.22 | 47.77 KB | 3.00 |
| StrongDAO_QueryDef_Class | 8.741 ms | 0.22 | 47.77 KB | 3.00 |
| StrongDAO_OpenStrongRecordset | 18.385 ms | 0.47 | 16.8 KB | 1.05 |
| DAO_OpenRecordset (Baseline) | 38.893 ms | 1.00 | 15.93 KB | 1.00 |
Note: Ratios are relative to DAO_OpenRecordset (Baseline). Lower is better.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Office.Interop.Access.Dao (>= 15.0.4420.1018)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.