efcore icon indicating copy to clipboard operation
efcore copied to clipboard

Allow value converters to change nullability of columns

Open ajcvickers opened this issue 4 years ago • 5 comments

Split off from #13850

By default, a column is nullable in the database if the property to which it is mapped is nullable. This is true even if the converter itself never converts nulls, since by default nulls are passed through unconverted. However, if the value converter converts nulls and ensures that no null values result from this conversion, then it it can make sense for the database column to be non-nullable.

ajcvickers avatar Apr 19 '21 14:04 ajcvickers

Note from triage: Ping @AndriySvyryd when working on this.

ajcvickers avatar Oct 21 '21 10:10 ajcvickers

Add SetIsNullable(this IMutableProperty, bool, in StoreObjectIdentifier) to allow configuring column nullability independently from property nullability.

AndriySvyryd avatar Oct 21 '21 20:10 AndriySvyryd

@ajcvickers I have the exact same issue as in [#27227] (https://github.com/dotnet/efcore/issues/27227) and have tried to use this as the solution but no joy.

I have an entity, MyEntity with a property defined as follows:

NullableTime NonNullableButNullInDB { get; set; }

NullableTime is a special type class which expects to be always populated in the model but may have a null DateTime associated with it in the DB. The existence and usage of this class is legacy and I can't get rid of it at the moment so have to be able to support it.

In ConfigureMappings, I am setting

protected override void ConfigureMappings(EntityTypeBuilder<MyEntity> entity) {
   entity.Property(e => e.NonNullableButNullInDB).Metadata.IsNullable = true;

but I get the following exception:

The property 'MyEntity.NonNullableButNullInDB' cannot be marked as nullable/optional because the type of the property is 'NullableTime' which is not a nullable type. Any property can be marked as non-nullable/required, but only properties of nullable types can be marked as nullable/optional.

at

   at Microsoft.EntityFrameworkCore.Metadata.Internal.Property.SetIsNullable(Nullable`1 nullable, ConfigurationSource configurationSource)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Property.set_IsNullable(Boolean value)
   at MyEntityConfiguration.ConfigureMappings(EntityTypeBuilder`1 entity)

Should I expect this to work now or has the support for this been reverted?

nettashamir-allocate avatar Feb 09 '22 09:02 nettashamir-allocate

@nettashamir-allocate This is the issue tracking the scenario you describe.

ajcvickers avatar Feb 14 '22 12:02 ajcvickers

Note to implementer: the main usage to be updated is https://github.com/dotnet/efcore/blob/7c90861f5787773548c53b33e1fddc3f4bbf2f86/src/EFCore.Relational/Extensions/RelationalPropertyExtensions.cs#L1077

AndriySvyryd avatar Jul 14 '22 18:07 AndriySvyryd

Note from triage: Implement this through https://github.com/dotnet/efcore/issues/27970.

ajcvickers avatar Oct 25 '22 08:10 ajcvickers