mikeg22 wrote:
Otis wrote:
mikeg22 wrote:
Just when I thought I understood the nullable fields concept...
I have set ConvertNullableReferenceTypesToDefaultValue to true in my project, but when I try to access theEntity.theNullableProperty.Value, I get an error: "Nullable object must have a value"
That project property, ConvertNullableReferenceTypesToDefaultValue, is for nullable REFERENCE types, e.g. string.
Your property seems a nullable VALUE type, e.g. Nullable(Of Integer)
I looked into why this is happening, and I see that the property Get is passing a "false" value to returnDefaultIfNull of EntityBase2.GetValue. Am I missing something, or should this be passing "true" if I have set ConvertNullableReferenceTypesToDefaultValue to true?
You should uncheck the checkbox for the field to generate it as a nullable type (in the entity editor). This can be controlled for NEW fields by the preference/project property: GenerateNullableFieldsAsNullableTypes.
As this doesn't affect an existing entity, you should use the plugin to set this flag in bulk.
(right-click entities, or an entity, Run plugin -> Sets GenerateAsNullableOfT Flas of Entity Fields Plug-in.)
Why is there only the option to convert nullable reference types to their default value? I'd actually want to convert all types to their default value, but maintain the nullable status of the field itself. The only way I can think to do this now is in the PostProcessValueToGet to just return the default value. Is this the recommended place for this?
That's a bit of a philosophical question so it might be my answer isn't what you want to hear, but we said that the default value for a nullable field is ... null. The idea is that a nullable field is, as all other fields, by definition undefined, it has void as value. 'null' is the representation of undefined, void.
So to have a nullable field set to a non-null value, you effectively set it to a value, which for YOU also represents undefined (e.g. 0 for an ID field which is always > 0), however for the entity it doesn't: it now has 2 values for undefined: null and the default value.
Ok, now to non-nullable fields, like a field which is of type int. These are the real problem: as said above, also an int field is initially null / undefined. However 'int' can't be null, so if you do:
int i = mycustomer.Id;
and Id is null, you'll get an exception, OR the framework returns a default value for null for a particular type. This is why these are converted to a default value.
Ok, now we'll run into a reference type which behaves like a value type: string. With strings there's a bit of a problem. Nullable<T> is for Value types, and string isn't a value type, it can be null. As we did set all fields to default values in the entity before v2 and we changed that to null in v2, we ran into a problem:
string s = myCustomer.Name;
if Name was undefined / null, s would suddenly become null, not string.Empty. As it's not a value type, there's no 'default' value returned for null for string as it can be null. To make existing code work properly, we added this option, so for string field which were null, you could get "" returned instead of null.