Getting DateTimeOffset property throws null ref exception

Posts   
 
    
Findev
User
Posts: 103
Joined: 08-Dec-2014
# Posted on: 08-Dec-2014 23:37:23   

Hi,

thank you for the great product!

I use Automapper to map custom entities to LLBLGen entities. One entity was failing with null reference exception, apparently when Automapper is mapping it tries to read the value first, I've never had that problem before, but interesting part was that this failing property was of DateTimeOffset type. I quickly isolated the issue into LinqPad:


    new EventEntity().EventId.Dump(); // int
    new EventEntity().DateCreated.Dump(); // DateTime
    new EventEntity().DateEventStart.Dump(); // DateTimeOffset

results:


0
1/1/0001 12:00:00 AM
NullReferenceException Object reference not set to an instance of an object. 

to my understanding this is an unexpected behavior simple_smile

Thank you!

P.S.: as usual - desperately waiting for the solution simple_smile

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 09-Dec-2014 06:29:02   

What is the stack trace? What LLBLGen version and runtime libraries are you using?

David Elizondo | LLBLGen Support Team
Findev
User
Posts: 103
Joined: 08-Dec-2014
# Posted on: 09-Dec-2014 09:31:45   

daelmo wrote:

What is the stack trace? What LLBLGen version and runtime libraries are you using?

When I was debugging it I found following:


/// <summary> The DateEventStart property of the Entity Event<br/><br/></summary>
/// <remarks>Mapped on  table field: "Events"."DateEventStart"<br/>
/// Table field type characteristics (type, precision, scale, length): DateTimeOffset, 0, 0, 0<br/>
/// Table field behavior characteristics (is nullable, is PK, is identity): false, false, false</remarks>
public virtual System.DateTimeOffset DateEventStart
{
    get { return (System.DateTimeOffset)GetValue((int)EventFieldIndex.DateEventStart, true); }
    set { SetValue((int)EventFieldIndex.DateEventStart, value); }
}

basically call to


GetValue((int)EventFieldIndex.DateEventStart, true);

returns null which is then casted to DateTimeOffset.

When I checked another property but of type DateTime there GetValue call actually returned DateTime.MinValue which then was casted to DateTime. My assumption is that GetValue method (when the second parameter is "true") should return a default value for given type: 0 for int, DateTime.MinValue for the DateTime and similarly a MinValue for the DateTimeOffset struct, but it returns null thus the error, this is identical to


 // LinqPad used here
 object v = null;
((DateTimeOffset)v).Dump();

which throws the same exception

Runtime is 4.2

Thank you!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 09-Dec-2014 12:12:24   

It's something that's related to default values provided for certain types. In short: when an entity class instance is created, reading the values of it, what does that mean? All fields are null when an entity instance is created, so they result in 'null' when reading the value. That won't work for some types, so we provide default values for some types, so reading a field then will return a proper 'null' value.

These values are in the class 'HelperClasses\TypeDefaultValues.cs'. There's no DateTimeOffset as that type wasn't in .NET for a long time, however it is now for a long time and we simply forgot to update the template.

In practice it's not such a big deal that the type isn't there (as reading from an unintialized entity class instance has no meaning) but in case you do want to have it fixed, I'll be happy to add DateTimeOffset to the template.

Frans Bouma | Lead developer LLBLGen Pro
Findev
User
Posts: 103
Joined: 08-Dec-2014
# Posted on: 09-Dec-2014 12:36:49   

Otis wrote:

It's something that's related to default values provided for certain types. In short: when an entity class instance is created, reading the values of it, what does that mean? All fields are null when an entity instance is created, so they result in 'null' when reading the value. That won't work for some types, so we provide default values for some types, so reading a field then will return a proper 'null' value.

These values are in the class 'HelperClasses\TypeDefaultValues.cs'. There's no DateTimeOffset as that type wasn't in .NET for a long time, however it is now for a long time and we simply forgot to update the template.

In practice it's not such a big deal that the type isn't there (as reading from an unintialized entity class instance has no meaning) but in case you do want to have it fixed, I'll be happy to add DateTimeOffset to the template.

Yes, basically I reported the issue because I thought that you may want to keep things consistent: either provide default values for everything or nothing. However, I do understand that you have many other reasons to consider regarding certain types.

In practice, I ran into this while using AutoMapper, as I mentioned I was mapping a custom entity to an LLBLGen entity and apparently when AutoMapper internally "new"s up the object it tries to read the values before mapping and exception happens. As a temporary workaround I've explicitly configured the mapping to first set DateTimeOffset.MinValue value to all DateTimeOffset properties.

Yes, it will be great if you could update the template simple_smile

Thank you!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 09-Dec-2014 12:38:29   

It's indeed best if the template gets more values. We'll update it. I hope to have a new one by the end of the day simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 09-Dec-2014 15:51:17   

Fixed template attached. Copy as administrator into the following folder:

<llblgen pro installation folder>\Frameworks\LLBLGen Pro\Templates\SharedTemplates\Net3.5\C#

Then regenerate the code. It should now have default values for datetimeoffset, timestamp, uint/ushort/ulong and sbyte besides the ones already there.

Attachments
Filename File size Added on Approval
typeDefaultValueInclude.template 1,766 09-Dec-2014 15:51.26 Approved
Frans Bouma | Lead developer LLBLGen Pro
Findev
User
Posts: 103
Joined: 08-Dec-2014
# Posted on: 09-Dec-2014 19:09:27   

Otis wrote:

Fixed template attached. Copy as administrator into the following folder:

<llblgen pro installation folder>\Frameworks\LLBLGen Pro\Templates\SharedTemplates\Net3.5\C#

Then regenerate the code. It should now have default values for datetimeoffset, timestamp, uint/ushort/ulong and sbyte besides the ones already there.

Fantastic tool, amazing support simple_smile

P.S.: dropped usage via LINQ in favor of QuerySpec simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 10-Dec-2014 11:31:59   

simple_smile

Frans Bouma | Lead developer LLBLGen Pro