dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.73k stars 3.17k forks source link

Allow applications to force nullability of columns #24685

Open ajcvickers opened 3 years ago

ajcvickers commented 3 years ago

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 commented 3 years ago

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

AndriySvyryd commented 3 years ago

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

nettashamir-allocate commented 2 years ago

@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?

ajcvickers commented 2 years ago

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

AndriySvyryd commented 2 years ago

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

ajcvickers commented 1 year ago

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