Does Dapper construct a new object for duplicated join results?

c# dapper

Question

When Dapper does a JOIN does it call the constructor for each a, b, c? or each unique a,b, c?

string sql = @"SELECT a.*, b.*, c.* 
               FROM A a
               JOIN B b ON b.Id = a.BId
               JOIN C c ON b.Id = c.BId";

var results = db.Query<A, B, C, A>(sql, (a, b, c) => { return a; });

For instance, if I have duplicates of c, will Dapper call c's constructor many times?

Or will it notice the Ids are the same between the rows and pass me the same object for all instances where the id is the same?

Edit:

After some testing, it looks like it does call the constructor multiple times for duplicate values.

Is there a simple way to work around this using the Dapper API?

Popular Answer

I'm going to propose my solution but leave this question open in case someone has a better idea.

This is what I've done:

List<dynamic> results = db.Query<dynamic, dynamic, dynamic, dynamic>(sql,
    (a, b, c) => { return new { a, b, c }; }).ToList(); // splitOn: 'Id'

List<dynamic> a_ids = new List<dynamic>();
List<dynamic> b_ids = new List<dynamic>();
List<dynamic> c_ids = new List<dynamic>();

List<A> unique_as = new List<A>();
List<B> unique_bs = new List<B>();
List<C> unique_cs = new List<C>();
foreach (var row in results)
{
    var a = row.a;
    var b = row.b;
    var c = row.c;
    if(!a_ids.Contains(a.Id)) unique_as.Add(new A(a.Id));
    if(!b_ids.Contains(b.Id)) unique_bs.Add(new B(b.Id));
    if(!c_ids.Contains(c.Id)) unique_cs.Add(new C(c.Id));
}

It would be nice if Dapper supported this in the future somehow, but until then, I hope this helps somebody else.




Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why