0

I have (simplified, obviously) tables such as:

public class Father
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Son> Sons { get; set; } = new List<Son>();
}

public class Son
{
    [Key]
    public int Id { get; set; }
    public int FatherId { get; set; }
    public string Name { get; set; }
}

In the db, I have 1 Father with ID = 1, and 3 Son with FatherId = 1.

I'd have my query such that:

conn.Query<Father, Son, Father>(
    @"SELECT f.*, s.* FROM Father f INNER JOIN Son s ON f.Id = s.FatherId WHERE f.Id = 1", 
    (f, s) => 
    {
        f.Sons.Add(s);
        return f;
    },
);

The query above gives me an IEnumerable of 3 Father with each Father containing a Son, rather than what I want: a single Father object with the Sons property containing 3 Son object.

I could do this by doing this, though I am not sure if this is the best way:

// Get father
var father = await connection.GetAsync<Father>(id);
// Get related sons
var sql = $"SELECT * FROM Son a WHERE a.FatherId = {father.Id}";
var sons = (await connection.QueryAsync<Address>(sql)).AsList();
// Stitch em all together
father.Sons.AddRange(sons);

I'm wondering if this is the best way to do this. How do we get a single object containing all the related objects using Dapper?

Farid
  • 872
  • 1
  • 13
  • 30

1 Answers1

4

There are some ways to do this, see How do I write one to many query in Dapper.Net?

I would prefer doing this as follows:

var fatherDictionary = new Dictionary<int, Father>();

var list = connection.Query<Father, Son, Father>(
    @"SELECT f.*, s.* FROM Father f INNER JOIN Son s ON f.Id = s.FatherId WHERE f.Id = 1",
    (f, s) =>
    {
        Father fatherEntry;

        if (!fatherDictionary.TryGetValue(f.Id , out fatherEntry))
        {
            fatherEntry = f;
            fatherEntry.Sons = new List<Son>();
            fatherDictionary.Add(fatherEntry.Id, fatherEntry);
        }

        fatherEntry.Sons.Add(s);
        return fatherEntry;
    })
.Distinct()
.ToList();

See example: https://dapper-tutorial.net/result-multi-mapping#example-query-multi-mapping-one-to-many

Selim Yildiz
  • 5,254
  • 6
  • 18
  • 28