Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

splitOn can't handle NULL value #266

Open
dynamicgl opened this issue Apr 2, 2015 · 12 comments
Open

splitOn can't handle NULL value #266

dynamicgl opened this issue Apr 2, 2015 · 12 comments

Comments

@dynamicgl
Copy link

Hi,
I noticed splitOn can't handle NULL value. for example: if I use sth like select c.*, c1.* from ..., when xxx_id is the first column of table c1 and its value is null, dapper will fail to convert it into the mapping type, instead return a null.

My work around is manual inserting a id field like select c.*, 1 as id, c1.* from ....
and dapper works well.

@NickCraver
Copy link
Member

I tried to clean up the issue...but I'm still not sure exactly what's happening here. Can you include a full example? I'm not sure if the splitOn is keyed on a null return but I can likely take a look next week - a full example would be easier to repro so we're on the same page and I can fix it accordingly.

@Dilip-Nandakumar
Copy link

Hi Nick,
Can you tell me what is the fix ? And how to overcome the issue so that i can make necessary code changes.

@wezzix
Copy link

wezzix commented Mar 25, 2016

I believe the issue is described in more detail here, and appear not to be resolved at the moment: http://stackoverflow.com/questions/10744728/dapper-multimap-doesnt-work-with-spliton-with-null-value

An allowSplitOnNull: true setting would be usable here, that would inspect all columns for values and not just the splitOn column. This is for scenarios where you have an object composed of several others, some of which are value objects without a meaningful id of their own.

@NickCraver
Copy link
Member

@wezzix thanks for adding context here - we'll take a look at scanning all columns so no new options are even necessary.

@BlackjacketMack
Copy link
Contributor

I opened a similar issue (
#222) but have come
to appreciate the simplicity of Dapper's existing behavior: if the spliton
value is null, the mapped object is null. Dapper needs a flag to say
'create this object', and that flag is the spliton value.

We use the pattern below quite a bit (because our PK's are not 'Id').
Sure, we get hit with the cost of a slightly larger resultset with
duplicate columns, but that just isn't our bottleneck. Everything cruises,
objects are fully hydrated, with no unexpected behavior. In regards to the
issue in this thread, the user could simply tack on the aliased spliton
column and know confidently if the returned object should be null or not.

(p = products table, c = optional categories table)

p.*,

c.CategoryID AS Id,

c.*

On Fri, Mar 25, 2016 at 2:19 PM, Nick Craver notifications@github.com
wrote:

@wezzix https://github.com/wezzix thanks for adding context here -
we'll take a look at scanning all columns so no new options are even
necessary.


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
#266 (comment)

@wezzix
Copy link

wezzix commented Mar 29, 2016

In your use case with LEFT JOIN I can fully understand that this is not an issue.
However the scenario I hinted above is quite distinct, where an object is composed of several other value objects (see DDD). Maybe an order with a billing and shipping address, or a contact with telephone number and prefix, all from a single table. As you can imagine, every field of these value objects can be null and there is no such thing as an Id.
In addition, if the data source is a temp table created by SELECT ... INTO followed by yet more INSERT for convenience, then the whole situation becomes quite unmanageable and random fields become riddled magic constants with comments about "must be not null due to Dapper splitOn issue".
Flattening the object structure to fit the SQL table would be a step back from object oriented design, so here, this is a real issue.
Thanks for the great work so far! Glad to hear you are taking a look at it.

@BlackjacketMack
Copy link
Contributor

Wezzix, We don't split on trivial value objects such as a 'DateRange'
object (with StartDate/EndDate properties). We flatten them out in private
properties on the object in question so they don't effect anything else and
directly wire their gets/sets to the public property. So, in the case of
an Employee class, there might be a private EmploymentStartDate{get{return
this.EmploymentDateRange.StartDate}{set{this.EmploymentDateRange.StartDate
= value;}}.

I'll grant you that it's slightly quirky. But it's totally transparent,
private to the class, unit-testable, and easy that at this point it's
second-nature to us. The object is totally composed of the objects you
want. The 'flattening' aspect of any value objects happens in private
properties (which Dapper knows about).

So the general rule of thumb for us is: split on tables (e.g. Employees),
flatten (privately) on value objects (e.g. DateRange, Currency, Telephone,
etc.). When you call Query() everything just gets wired in
perfectly.

On Tue, Mar 29, 2016 at 8:38 AM, wezzix notifications@github.com wrote:

In your use case with LEFT JOIN I can fully understand that this is not an
issue.
However the scenario I hinted above is quite distinct, where an object is
composed of several other value objects (see DDD). Maybe an order with a
billing and shipping address, or a contact with telephone number and
prefix, all from a single table. As you can imagine, every field of these
value objects can be null and there is no such thing as an Id.
In addition, if the data source is a temp table created by SELECT ... INTO
followed by yet more INSERT for convenience, then the whole situation
becomes quite unmanageable and random fields become riddled magic constants
with comments about "must be not null due to Dapper splitOn issue".
Flattening the object structure to fit the SQL table would be a step back
from object oriented design, so here, this is a real issue.
Thanks for the great work so far! Glad to hear you are taking a look at it.


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#266 (comment)

@micgruber
Copy link

Hi, I'm using dapper 1.50.2 but the problem still appears. Is there already a better fix available than adding a surrogate column?

@branko-d
Copy link

The problem is still present under Dapper 1.50.5 (I tried under SQL Server 2017, if that matters).

Adding a dedicated non-NULL split column such as...

SELECT
   -- first object columns
   0 SPLIT,
   -- second object columns
FROM
   ...

...solves it, but this behavior is unexpected and it took me quite a while to figure out the problem (under a ton of other code). I don't think the current behavior should be the default.

@dc-p8
Copy link

dc-p8 commented Sep 11, 2018

i still have the same problem in 1.50.5
I also commented the stackoverflow topic https://stackoverflow.com/questions/10744728/dapper-multimap-doesnt-work-with-spliton-with-null-value/52279842#52279842

@NickCraver NickCraver added the area:settings Settings! label May 11, 2021
@nilact
Copy link

nilact commented Sep 8, 2021

Any update on this? Is this going to be fixed in the near future release?

The OP started this thread in 2015.

@KaptainRiversnapps
Copy link

Still an issue, specifically for splitting keyless data returned from a stored procedure into multiple objects. If the splitOn column is null, the object won't get mapped at all even if other fields in the object have values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants