<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/handling-relationships-in-dapper-2pgxzo4h0" -->

---
title: Handling Relationships in Dapper | daily.dev
description: Covers how to map one-to-one, one-to-many, and many-to-many relationships in Dapper using QueryAsync with multiple type parameters and the splitOn parameter....
canonical: https://daily.dev/posts/handling-relationships-in-dapper-2pgxzo4h0
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Handling Relationships in Dapper | daily.dev
og:description: Covers how to map one-to-one, one-to-many, and many-to-many relationships in Dapper using QueryAsync with multiple type parameters and the splitOn parameter....
og:url: https://daily.dev/posts/handling-relationships-in-dapper-2pgxzo4h0
og:image: https://api.daily.dev/og/posts/2pgXZo4h0.png
og:image:alt: Handling Relationships in Dapper
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Handling Relationships in Dapper

**[NikolaTech](https://daily.dev/sources/nikolatech)** · 6 min read · 0 upvotes · 0 comments

## Summary

Covers how to map one-to-one, one-to-many, and many-to-many relationships in Dapper using QueryAsync with multiple type parameters and the splitOn parameter. Shows SQL joins paired with C# code, and explains the dictionary pattern needed to avoid duplicate parent objects when joining one-to-many or many-to-many data.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://nikolatech.net/blogs/dapper-relationship-asp-dotnet-core>

## Questions this post answers

### How do I map a one-to-many relationship with Dapper without getting duplicate parent objects?

Use a dictionary keyed by the parent entity's id when calling QueryAsync with a LEFT JOIN. For each row, check if the parent already exists in the dictionary; if not, add it and initialize its child list, then append the related child record to that existing instance's list, repeating for every row in the result set.

_Developers wiring up Dapper joins can save this pattern for the next one-to-many mapping headache on daily.dev._

### What does the splitOn parameter do in Dapper's QueryAsync method?

It tells Dapper where a new object begins in a joined query result. Dapper reads columns left to right filling the first object's properties, and when it hits a column matching the splitOn name (commonly 'Id'), it starts mapping subsequent columns to the next object type specified in the QueryAsync generic parameters.

_Anyone debugging multi-table Dapper queries can keep mapping tricks like this handy via daily.dev._

## Similar posts on daily.dev

- [Dapper in Depth with ASP.NET Core 10](https://daily.dev/posts/dapper-in-depth-with-asp-net-core-10-oad4bk2bw) · C\# Corner · 1 upvotes · 0 comments
- [How to Work With Dapper in .Net](https://daily.dev/posts/how-to-work-with-dapper-in-net-yzgrlyllb) · freeCodeCamp · 17 upvotes · 0 comments
- [One-to-Many Relationships](https://daily.dev/posts/one-to-many-relationships-swnrc9u0p) · Larablog · 1 upvotes · 0 comments

---

Tags: [#.net](https://daily.dev/tags/.net), [#sql](https://daily.dev/tags/sql), [#c#](https://daily.dev/tags/c#)

[View this post on daily.dev](https://daily.dev/posts/handling-relationships-in-dapper-2pgxzo4h0)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Handling Relationships in Dapper","url":"https://daily.dev/posts/handling-relationships-in-dapper-2pgxzo4h0","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/handling-relationships-in-dapper-2pgxzo4h0"},"datePublished":"2026-10-04T13:06:58.274Z","dateModified":"2026-10-04T13:11:54.174Z","description":"Covers how to map one-to-one, one-to-many, and many-to-many relationships in Dapper using QueryAsync with multiple type parameters and the splitOn parameter....","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/5c48342e136c74d6c43fc658f12efd45?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/5c48342e136c74d6c43fc658f12efd45?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"NikolaTech","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"NikolaTech","logo":"https://media.daily.dev/image/upload/s--1h2fO6FL--/f_auto,q_auto/v1791119050/logos/nikolatech?_a=BAMAMicg0","url":"https://daily.dev/sources/nikolatech"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/handling-relationships-in-dapper-2pgxzo4h0","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":".net,sql,c#","timeRequired":"PT6M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"NikolaTech","item":"https://daily.dev/sources/nikolatech"},{"@type":"ListItem","position":3,"name":"Handling Relationships in Dapper"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/handling-relationships-in-dapper-2pgxzo4h0#faq","mainEntity":[{"@type":"Question","name":"How do I map a one-to-many relationship with Dapper without getting duplicate parent objects?","acceptedAnswer":{"@type":"Answer","text":"Use a dictionary keyed by the parent entity's id when calling QueryAsync with a LEFT JOIN. For each row, check if the parent already exists in the dictionary; if not, add it and initialize its child list, then append the related child record to that existing instance's list, repeating for every row in the result set. Developers wiring up Dapper joins can save this pattern for the next one-to-many mapping headache on daily.dev."}},{"@type":"Question","name":"What does the splitOn parameter do in Dapper's QueryAsync method?","acceptedAnswer":{"@type":"Answer","text":"It tells Dapper where a new object begins in a joined query result. Dapper reads columns left to right filling the first object's properties, and when it hits a column matching the splitOn name (commonly 'Id'), it starts mapping subsequent columns to the next object type specified in the QueryAsync generic parameters. Anyone debugging multi-table Dapper queries can keep mapping tricks like this handy via daily.dev."}}]}
```

