Magnus Mårtensson
Microsoft Regional Director, Azure MVP, CEO Loftysoft
Avirag Jain
Director & CTO R Systems
Mahesh Chand
Founder C# Corner, CEO Mindcracker
Chris Gali
CEO & Co-Founder Graphite
Subinder Khurana
Chief Architect StoryProcess, Founder NASSCOM DeepTech Club
Bryan Rishforth
Investor, Chairman Graphite
Bryn Everson
Director Biz Dev Graphite
Raj Tiwari
Digital Transformation Leader, Futurist and Visionary
Joseph Guadagno
Microsoft MVP, Lead Quicken Loans
Nikita Sachdev
Entrepreneur, Blockchain Enthusiast & Advisor, Social Media Influencer
Doug Wagner
COO & Founder Adapt Technical Group
Ritesh Modi
Architect, Senior Evangelist, Cloud Architect
Crystal Wenrick
Director Communications Mindcracker
Allen O’Neill
Microsoft MVP, Consulting Engineer/Architect
Praveen Kumar
CEO MCN Solutions
Chris Love
Founder Love2Dev, Microsoft MVP, Author
Sanjay Vyas
Microsoft Regional Director, Microsoft MVP, Founder & CEO SkillLabs Technologies
Veena Sarda
Deep Learning Consultant, Author
Sekhar Srinivasan
C# Corner MVP, Microsoft Certified Trainer, Pluralsight Author
Lalit Bansal
Founder & CEO - EIY SYS
Navdeep Garg
CEO Revinfotech
Prakash Tripathi
Tech Manager/Leader, Microsoft MVP, Blogger
Bhavna Jain
Breakthrough Consultant
Naveen Sharma
Enterprise Architect, Leadership Coach, Author
Vidya Vrat Agarwal
Principal Architect, Microsoft MVP, Author
Sheetal Agarwal
Founder Clownselors, Medical Clown, Trainer
Abhishek Kant
Founder GTM Catalyst
Vishnu Saran
Founder & CEO VoiceQube
Sandeep Soni
Founder & CEO Deccansoft, Microsoft Certified Trainer
Parveen Malik
AVP InfoSec & Vulnerability Management, Information Security Expert
Nitin Pandit
Microsoft MVP, Developer Evangelist, Author
Niloshima Srivastava
C# Corner MVP, Tech Architect, Trainer, Blogger
Bala Chirtsabesan
Senior Software Engineer at Microsoft, Author
Manoj Mittal
Sr. Technical Architect, C# Corner MVP, Author
Chandni Di
Co-Founder Voice of Slum
Vithal Wadje
Technical Lead, Microsoft MVP, Author
Shivam Ahuja
Founder SkillCircle, Business Mentor
Chervine Bhiwoo
Solution Architect, Microsoft MVP, Author
Saurabh Jain
Vice President Paytm, Founder Fun2Do Labs, Author
Vinay Solanki
Head IoT at Lenovo, Founder IoT-NCR
Anshu kumari
Founder Blockchainkids, Inventor, Trainer
Amit Singal
CEO Startup Buddy
Dev Pratap
Co-Founder & CEO Voice of Slum
Amey Vartak
Technology Consultant, Full Stack Developer, C# Corner MVP, Author
Viswanatha Swamy
Principal Software Engineer, C# Corner MVP, Author
Sanket Verma
Research Engineer @ Ballistics (Forensics) and Chair, PyData Delhi
Sourabh Somani
Lead Developer, Microsoft MVP, Author
Abhishek Mishra
Software Architect, C# Corner MVP, Author
Siddharth Vaghasia
Technical Consultant, C# Corner MVP, Blogger
Bassam Alugili
Senior Software Specialist, Database Expert
S Ravi Kumar
Solution Architect, C# Corner MVP, Author
Sundaram Subramanian
Full Stack Developer, C# Corner MVP, Speaker
Deepesh Somani
Solution Architect, Microsoft MVP, Author
Debasis Saha
Technical Project Manager, C# Corner MVP, Blogger, Author
Vipul Jain
Software Architect, C# Corner MVP, Author
Akshay Patel
Technical Architect, Microsoft Certified Trainer, C# Corner MVP, Author
Stephen Simon
RPA Developer, Evangelist, Author
Vivek Sharma
Founder Kingster636, AR/VR Specialist
Jeetendra Gund
Technical Lead, C# Corner MVP, Author
Sujal Beniwal
AI Enthusiast, Student
M Viknaraj
Microsoft MVP, Azure Architect, Author
Prasham Sabadra
Software Architect, C# Corner MVP, Trainer, Author
Aakash Maurya
Senior Developer, C# Corner MVP, Speaker
Ankit Sharma
Senior Software Engineer, C# Corner MVP, Author
Mangesh Gaherwar
Team Lead, C# Corner MVP, Author
Viral Jain
Technical Consultant, C# Corner MVP, Author
Bhasker Das
Solution Architect, Evangelist
Manish Dwivedi
Associate Project Manager
Ck Nitin
Programmer, Author
Rohit Gupta
Technical Trainer, Author
Manish Tewatia
Full-stack Marketer, UX Designer
Bhavya Gaur
Technical Illustrator
Rohit Tomar
SEO/SMO Expert
Web Track
Cloud & Data Track
Dev Track
Registration & Breakfast
Future of Desktop Apps with JS (ElectronJs)
Nitin Pandit
Building Serverless Microservices Using Microsoft Azure
Vithal Wadje
Innovating RPA: A Robot for Every Person
Stephen Simon
Managing Cloud Storage Accounts using Logic Apps
Viknaraj Manogararajah
Data visualization using Python
Sekhar Srinivasan
Going Cross platform with AR Foundation
Vivek Sharma
Keynote
Managing your Azure dependencies in ASP.NET Core apps using VS
Bala Chirtsabesan
Securing Applications on Intelligent Azure
Abhishek Mishra
Getting started with Blazor the Framework of Future
S Ravi Kumar
Lunch
Build Progressive Web Apps using Angular 9
Debasis Saha
Build and deploy to any platform using Azure DevOps
Chervine Bhiwoo
Deep Dive in Azure Service Bus
Akshay Patel
Build a Native Mobile Application using React Native and JavaScript
Joseph Guadagno
Making sense of Web Job, Web Job SDK and Functions in Azure
Prakash Tripathi
CloudFront Distribution in AWS
Viral Jain
Tea Break
Introduction to PowerBI
Aakash Maurya
Build Advanced SPFx solutions with React and Graph API
Siddharth Vaghasia
Build Business Intelligence Analyst (BIA) Skills
Sundaram Subramanian
Deep dive of Power Platform – AI BUILDER
Prasham Sabadra
Panel 1
What's new in SharePoint development
Vipul Jain
Build a SSO (Single Sign On) based Native JavaScript application with Microsoft Identity within 10 minutes
Manoj Mittal
Panel 2
Applications and working of AI
Veena Sarda
Deploying serverless API's with .Net core 3.0 on AWS & Azure
Amey Vartak
Panel 3
Blockchain with .NET Core (Ark)
Anshu Kumari
Closing Note & Prize Distribution
Dev Track
Cloud Track
Architecture Track
Emerging Tech Track
Registration & Breakfast
Creating Full-Stack Web Apps Using Server-Side Blazor
Ankit Sharma
Real time face recognition with MS Cognitive Services
Niloshima Srivastava
Building Scalable APIs with GraphQL
Jeetendra Gund
Future of development with AI and Blockchain
Navdeep Garg
Debugging Tips and Tricks with Visual Studio 2019
Joseph Guadagno
Azure Containers
Abhishek Kant
Enterprise Architecture
Naveen Sharma
Bot Framework - learn it fast and look like a boss!
Allen O’Neill
Keynote
.Net Core & C# 8 Performance
David McCarter
Working with Azure kubernetes services
Ritesh Modi
Becoming an Architect
Vidyavrat Agarwal
Why Techies Need to Learn Product Management
Saurabh Jain
Lunch
Build a rules engine in .Net Core
Sanjay Vyas
Building CI and CD Pipeline using Azure DevOps
Sandeep Soni
Entity Framework Core - Tips and Tricks, Performance Optimization, and Tuning
Bassam Alugili
Hacking your way into Data Science
Sanket Verma
Speed up your .Net Core Website
Sourabh Somani
Azure
Magnus Mårtensson
Demystifying Open Distro for Elasticsearch
Suman Debnath
Future of Data
Shivam Ahuja
Tea Break
gRPC with C# and .Net Core
Mangesh Gaherwar
Panel 1
Essentials of Cloud security
Parveen Malik
Power platform and Dynamics 365
Deepesh Somani
Microservices - the gRPC Way
Viswanatha Swamy
Panel 2
Reserved
Reserved
Closing Note & Prize Distribution
High-performance data access with Dapper in C#
Dapper is a lightweight micro-ORM for .NET that stays close to SQL while removing repetitive object-mapping code from ADO.NET. It builds parameterised commands, materialises results into C# records or classes, and adds little abstraction overhead. For read-heavy services and carefully controlled writes, that balance can produce fast data access without giving up control of the database.
Australian delivery teams often juggle on-premises SQL Server estates with Azure SQL Database deployments. Teams in Sydney, Melbourne and Brisbane serve customers across AEST and AEDT, and hosted applications may sit far from internal databases. Dapper suits this mixed environment because it runs in APIs, workers and serverless functions without requiring a particular hosting model.
The gains come from disciplined use, not from an ORM label. Correct parameter mapping, sensible connection handling, targeted indexes and measured execution plans work together. The practices below show how to use Dapper for high-performance data access in C#, with examples that remain effective on local workstations, in Azure and inside background processing systems.
Why Dapper suits .NET data access
Dapper sits close to ADO.NET. It handles command definition, parameter binding and simple row mapping, but leaves queries visible and predictable. That makes it attractive for services with stable SQL, modest domain objects and high query volume. It also avoids automatic change tracking, lazy loading and generated provider SQL, behaviours that can be useful elsewhere but unwanted in a latency-sensitive path.
The performance gain comes from doing less unnecessary work, not from changing SQL automatically. A Dapper call can still trigger a broad scan, duplicate joins or hold results in memory. Compare it with EF Core and hand-written ADO.NET using production-like data, measuring end-to-end latency and server resource use rather than relying on synthetic microbenchmarks alone.
Setting up a focused .NET project
Use a currently supported .NET release and add the Dapper and Microsoft.Data.SqlClient packages. Keep connection strings outside source control: user secrets suit local work, while deployed applications should retrieve credentials from a managed secret service. Australian teams frequently run separate development, test and production estates, so configuration mistakes deserve isolation from the start.
Create a repository around a narrow business purpose rather than a universal data gateway. Expose asynchronous methods, accept explicit filters and pass a CancellationToken through each command. This small surface makes the SQL visible to tests, lets the team replace a query without redesigning an entire ORM context, and supports predictable behaviour in APIs and workers.
A typical lookup keeps the query beside the mapping it returns:
using Dapper;
using Microsoft.Data.SqlClient;
public sealed class CustomerRepository
{
private readonly string _connectionString;
public CustomerRepository(string connectionString) =>
_connectionString = connectionString;
public async Task<Customer?> FindAsync(
int id, CancellationToken cancellationToken)
{
await using var connection = new SqlConnection(_connectionString);
return await connection.QuerySingleOrDefaultAsync<Customer>(
new { Id = id },
cancellationToken: cancellationToken);
}
}
Mapping parameters and reading results
Dapper binds anonymous objects or dictionaries to SQL parameters by matching names, so a property named Id supplies @Id. It maps returned columns to C# properties using a case-insensitive default. Always pass values as parameters: string concatenation creates injection risks and produces a different query for every value, defeating SQL Server's execution-plan cache.
Multiple result sets can share one command and connection:
using var connection = new SqlConnection(connectionString);
using var grids = await connection.QueryMultipleAsync(
new CommandDefinition(
"""
SELECT Id, Name, Email
FROM dbo.Customers;
SELECT COUNT(*)
FROM dbo.Orders
WHERE CustomerId = @CustomerId;
""",
new { CustomerId = customerId },
cancellationToken: cancellationToken));
var customers = (await grids.ReadAsync<Customer>()).ToList();
var orderCount = await grids.ReadSingleAsync<int>();
Use records for immutable query results and explicit aliases such as TotalAmount when database and C# names differ. Dapper can also split a joined row across several types using splitOn and combine the fragments in code. Fetching related rows in one round trip avoids the N+1 pattern of querying every order or invoice separately for the same customer.
Large exports need care because Dapper buffers each result set by default. Use the unbuffered option, represented by CommandFlags.None, to stream rows and keep memory usage bounded. The trade-off is an occupied connection until enumeration finishes, so dispose the reader promptly and avoid leaving a stream open while waiting for another service.
Building queries that stay efficient
Let SQL perform filtering, joins, aggregation and sorting. Dapper will not optimise an inefficient statement for you, and moving those operations into C# usually increases transferred data. Use indexed columns with sargable predicates, avoid wrapping indexed fields in functions and request only the columns the application needs. Stored procedures can also work well when their plans are tested and their contracts are stable.
A grouped report can use a CommandDefinition for explicit timeout and cancellation:
var totals = await connection.QueryAsync<OrderTotal>(
new CommandDefinition(
"""
SELECT CustomerId,
COUNT(*) AS OrderCount,
SUM(Total) AS LifetimeValue
FROM dbo.Orders
WHERE CreatedAt >= @From
AND CreatedAt < @To
GROUP BY CustomerId;
""",
new { From = fromUtc, To = toUtc },
cancellationToken: cancellationToken,
commandTimeout: 30));
Inspect actual execution plans under realistic volumes, then add or adjust indexes based on the measured workload. Use UTC boundaries for reporting periods because daylight-saving changes between AEST and AEDT can otherwise move results. Connection reuse can shave latency, yet it cannot compensate for a query that scans millions of irrelevant rows.
Controlling connections and transactions
Open connections as late as possible and dispose them promptly. Microsoft.Data.SqlClient pools connections by default, so disposal returns a connection to the pool rather than destroying the session. Use one connection per request in web applications and per unit of work in workers. Never share a mutable SqlConnection between concurrent operations, and avoid holding it open while calling an unrelated network service.
For related writes, pass the same transaction to every Dapper command:
await using var connection = new SqlConnection(connectionString);
await connection.OpenAsync(cancellationToken);
await using var transaction =
await connection.BeginTransactionAsync(cancellationToken);
try
{
var updated = await connection.ExecuteAsync(
new CommandDefinition(
"""
UPDATE dbo.Accounts
SET Balance = Balance - @Amount
WHERE Id = @Id AND Balance >= @Amount;
""",
new { Amount = amount, Id = accountId },
transaction,
cancellationToken: cancellationToken));
if (updated != 1)
throw new InvalidOperationException("Insufficient balance.");
await connection.ExecuteAsync(
new CommandDefinition(
"INSERT INTO dbo.Entries (AccountId, Amount) VALUES (@Id, @Amount);",
new { Id = accountId, Amount = amount },
transaction,
cancellationToken: cancellationToken));
await transaction.CommitAsync(cancellationToken);
}
catch
{
await transaction.RollbackAsync();
throw;
}
Dapper has no ambient transaction, so every statement must receive the transaction object. Retry policies must cover the entire unit of work without duplicating a debit, inventory change or payment. A database in another Australian state can spend a meaningful share of a timeout on network travel, so measure connection time separately from execution time before extending command limits.
Operational habits for dependable production data access
Production failures need context without exposing sensitive data. Log elapsed time, a command identifier, affected-row counts and exception details, but avoid customer records, credentials and full parameter payloads. For event-driven capture, this serverless ingestion walkthrough provides a useful reference for placing Azure Functions between incoming work and durable storage.
Australian privacy obligations, including the Privacy Act 1988 and the Australian Privacy Principles, shape how personal information is collected and retained. Limit returned columns, protect exported files and apply suitable access controls and retention periods. Logging is still data processing, so give operational telemetry the same scrutiny as an application database.
Before deployment, focus on these design checks:
- Keep SQL under source control and review query changes alongside schema changes.
- Use separate credentials and connection settings for local, test and production.
- Run representative load tests against the intended Azure SQL or SQL Server version.
At runtime, make the following signals visible:
- Track command duration, timeout failures and connection-pool saturation.
- Alert on repeated rollback failures and unusual query-volume increases.
- Sample execution plans after significant schema or workload changes.
Comparing Dapper with other approaches
Dapper, EF Core and raw ADO.NET occupy different points on the control-versus-convenience spectrum. Dapper keeps SQL explicit and mapping compact, which suits APIs, reporting services and predictable schemas. EF Core offers change tracking, migrations and richer persistence patterns for domain-heavy applications. Raw ADO.NET remains appropriate for specialised bulk paths or infrastructure needing complete control of provider behaviour.
One application can use more than one approach: EF Core might manage aggregate lifecycles while Dapper serves a high-volume read model. Choose by workload, then benchmark comparable queries with realistic indexes, data volumes and network latency. Include memory pressure and server CPU in the results, since a fast client can still overload SQL Server with poorly filtered requests.
For straightforward SQL and modest mapping needs, Dapper offers a compact, predictable layer between application code and the database. Its performance depends on the quality of each command, the surrounding connection strategy and the database design.
| Approach | Strongest fit | Main trade-off | Typical fit |
|---|---|---|---|
| Dapper | Transparent SQL and lightweight mapping | Requires disciplined queries and manual relationship handling | APIs, services and high-volume read paths |
| EF Core | Change tracking, migrations and complex aggregates | More runtime work and database-specific behaviour | Transaction-heavy business applications |
| Raw ADO.NET | Full control over provider operations | Verbose mapping and repetitive boilerplate | Bulk operations and specialised infrastructure |
1, CBD, Maharaj Surajmal Road, Near Yamuna Sports Complex, Delhi, 110032
GENERAL QUERIES
Manish Tewatia
manish@csharpcon.com
+91-9718-431-042
TICKET QUERIES
Atul Gupta
conference@csharpcon.com
+91-9910-125-804