Was support for SplitOn omitted by design from the QuerySingle and QueryFirst functions?
Have I overlooked something or misunderstood their intended purpose?
Since their intended purpose is just querying for a single type, there's no need to split for multiple types.
Hi, thanks for the reply. I imagine wanting to return a single instance/type filled with several child properties is a fairly common use-case. (For example: User with User.Team filled) So, I'm not quite sure I understand the reasoning behind limiting their purpose.
I can see where this might get tricky with one-to-many joins and getting unexpected results. If I were trying to return a single Order with Order.Items filled using a JOIN then you would probably end up only with the first Item of the Order. But I'm not sure this scenario should hold back the convenience of a SplitOn for the previous scenario.
In this case, you'd use a Query<T, T2, TResult>
call (what we call multi-map), that's the only case in which a splitOn
makes sense...where does the split happen before reading the next object? It defaults to Id
columns. Since the methods you're talking about _only_ return the one type...there's no split involved at all, and therefore no parameter.
Understood. I'm not arguing to use SplitOn with the functions as they are now. I was assuming that support for SplitOn implied adding support for additional types <T,T2,T3,...>
.
That said, the real question is will QuerySingle
& QueryFirst
have multi-map support added in the future? On the surface they appear to be simple and convenient helpers that are currently limited. I was merely curious as to whether there was a fundamental design issue that I wasn't considering for why additional types <T,T2,T3,...>
were omitted.
It feels a bit silly to be able to do this when only T is involved:
var user = conn.QueryFirst<User>("SQL");
But then have to switch to this just because I want to multi-map:
var user = conn.Query<User, Address, User>("SQL", ...).First();
I think the honest answer is "that's just more overloads than we want to maintain". And generally, when loading _only a single row_, that optimization passed to the data provider is less effectual in terms of overall impact percentage. We already have a lot of methods, and async methods, and generic overload counts and...it's just a matter of: is the use case percentage or performance benefit worth maintaining x
amount bigger code?
Think about every API change (e.g. oops, we need to add parameter X to all of these), which means _another_ set of them to maintain backwards compatibility. That's just one example, but the maintenance and noise really adds up on these, so unless there's a high demand for such overloads, we're admittedly reluctant to add them.
Say I'm querying single Order and want to join in the customer Profile. My Order looks something like:
C#
public class Order
{
public int Id { get; set; }
public decimal Total { get; set; }
public Customer Customer { get; set; }
}
Am I missing something, or is this the use case described for QueryFirst having SplitOn? Right now I'm using Query
and then .FirstOrDefault()
. I suppose I could use a custom map, but that sounds tedious. I could also use two queries but that seems ridiculous.
I too would like to know how to handle @r-tanner-f 's situation. Because I'm in that same boat.
Yep, I'm also in need of this scenario. Thanks
Same. This is an extremely common use case.
Most helpful comment
Say I'm querying single Order and want to join in the customer Profile. My Order looks something like:
C# public class Order { public int Id { get; set; } public decimal Total { get; set; } public Customer Customer { get; set; } }
Am I missing something, or is this the use case described for QueryFirst having SplitOn? Right now I'm using
Query
and then.FirstOrDefault()
. I suppose I could use a custom map, but that sounds tedious. I could also use two queries but that seems ridiculous.