Dapper

Lightweight .NET micro-ORM that extends IDbConnection with convenience methods for SQL query execution and result mapping. Dapper adds: connection.QueryAsync<Agent>(sql, params) for typed query results, connection.ExecuteAsync(sql, params) for inserts/updates, connection.QueryFirstOrDefaultAsync<Agent>(sql, params), multi-mapping (JOIN results to multiple objects), QueryMultiple for multiple result sets, and stored procedure execution. Dapper maps SQL column names to C# property names automatically (case-insensitive). No migrations, no change tracking, no LINQ — just SQL + fast object mapping. StackOverflow was built with Dapper. Excellent for performance-critical agent data access paths and complex reporting queries.

Evaluated Mar 06, 2026 (0d ago) v2.x
Homepage ↗ Repo ↗ Developer Tools dotnet csharp sql micro-orm performance stored-procedures ado-net queries
&#9881; Agent Friendliness
67
/ 100
Can an agent use this?
&#128274; Security
87
/ 100
Is it safe for agents?
&#9889; Reliability
90
/ 100
Does it work consistently?

Score Breakdown

⚙ Agent Friendliness

MCP Quality
--
Documentation
88
Error Messages
85
Auth Simplicity
90
Rate Limits
95

🔒 Security

TLS Enforcement
90
Auth Strength
85
Scope Granularity
82
Dep. Hygiene
90
Secret Handling
88

Dapper does NOT protect against SQL injection if you use string interpolation — always use parameterized queries with anonymous objects or DynamicParameters. Store connection strings in Azure Key Vault or .NET User Secrets. Enable TLS for all agent database connections (Encrypt=True in SQL Server connection string).

⚡ Reliability

Uptime/SLA
92
Version Stability
92
Breaking Changes
90
Error Recovery
85
AF Security Reliability

Best When

Your .NET agent service has performance-critical data access paths, complex reporting queries, or stored procedure integration where EF Core's generated SQL is insufficient — Dapper gives you full SQL control with minimal mapping boilerplate.

Avoid When

You need database migrations, you want LINQ queries, or your agent data access is simple CRUD where EF Core's convenience outweighs Dapper's performance.

Use Cases

  • High-performance agent reporting query — await connection.QueryAsync<AgentMetrics>("SELECT a.id, COUNT(t.id) as tool_calls FROM agents a LEFT JOIN tool_calls t ON a.id = t.agent_id GROUP BY a.id WHERE a.created_at > @since", new { since = DateTime.UtcNow.AddDays(-7) }) executes complex agent analytics without ORM overhead
  • Agent stored procedure execution — await connection.QueryAsync<Agent>("sp_GetActiveAgents", new { UserId = userId }, commandType: CommandType.StoredProcedure) calls stored procedure and maps results to Agent objects
  • Multi-table agent query with Dapper multi-mapping — connection.QueryAsync<Agent, Tool, Agent>(sql, (agent, tool) => { agent.Tools.Add(tool); return agent; }, splitOn: "ToolId") maps JOIN results to nested Agent objects
  • Bulk agent insert performance — await connection.ExecuteAsync("INSERT INTO agents (name, user_id) VALUES (@Name, @UserId)", agentList) batches multiple agent inserts efficiently via Dapper's enumerable parameter support
  • Mixed Dapper + EF Core agent repository — use EF Core for standard CRUD and Dapper for complex agent reporting queries where LINQ-generated SQL is suboptimal; both share same SqlConnection for agent transaction consistency

Not For

  • Schema migrations — Dapper has no migration system; use EF Core migrations, Flyway, or DbUp for agent database schema management alongside Dapper
  • Complex object graphs — Dapper requires explicit JOIN + multi-mapping for nested objects; EF Core's Include() is simpler for agent models with multiple levels of related entities
  • Teams who prefer no-SQL approach — Dapper requires writing SQL; for agent services where team doesn't want SQL, EF Core LINQ queries provide abstraction

Interface

REST API
No
GraphQL
No
gRPC
No
MCP Server
No
SDK
Yes
Webhooks
No

Authentication

Methods: none
OAuth: No Scopes: No

Dapper extends IDbConnection — auth via connection string. Use SQL Server integrated auth or connection string credentials. Azure Managed Identity supported via SqlConnection token configuration.

Pricing

Model: open_source
Free tier: Yes
Requires CC: No

Dapper is Apache 2.0 licensed, maintained by StackOverflow/DapperLib. Free for all use.

Agent Metadata

Pagination
offset
Idempotent
Partial
Retry Guidance
Not documented

Known Gotchas

  • SQL injection via string interpolation — var agents = conn.Query<Agent>($"SELECT * FROM agents WHERE name = '{name}'") is SQL injection vulnerability; ALWAYS use parameterized queries: conn.QueryAsync<Agent>("SELECT * FROM agents WHERE name = @Name", new { Name = name }); Dapper parameterizes when using anonymous objects, never string interpolation
  • Column name mapping is case-insensitive but exact name match — Dapper maps SQL column 'agent_name' to C# property 'AgentName' only if using Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true; without this setting, snake_case DB columns don't map to PascalCase C# agent properties; configure once at startup
  • Connection must be open or Dapper auto-opens — Dapper can open closed connections automatically but won't close them; for agent services managing connection lifetime manually, open connection before query and ensure disposal; connection leaks in agent services exhaust SQL Server connection pool
  • QueryMultiple disposable must be disposed — var multi = await conn.QueryMultipleAsync(sql, params); var agents = multi.Read<Agent>(); forgetting await multi.DisposeAsync() leaves server-side result set cursor open; wrap in using statement for agent multi-result queries to prevent cursor resource leaks
  • Dynamic parameters required for dynamic column agent queries — conn.QueryAsync<Agent>(sql, new DynamicParameters(dict)) for agent queries with runtime-determined parameters; anonymous objects compile-time only; DynamicParameters.Add(name, value, dbType) for typed parameter binding in agent dynamic query builders
  • Multi-mapping splitOn must match exact column name — QueryAsync with multi-mapping splitOn: 'ToolId' requires SQL to return column named exactly 'ToolId' (case-sensitive on some DBs) as boundary between mapped types; wrong split column causes entire second object to be null in agent JOIN mapping without error

Alternatives

Full Evaluation Report

Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for Dapper.

$99

Scores are editorial opinions as of 2026-03-06.

5211
Packages Evaluated
26151
Need Evaluation
173
Need Re-evaluation
Community Powered