/// <summary> /// Sets the <see cref="NpgsqlValueGenerationStrategy" /> to use for the property. /// </summary> /// <param name="property">The property.</param> /// <param name="value">The strategy to use.</param> /// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param> public static void SetValueGenerationStrategy( [NotNull] this IConventionProperty property, NpgsqlValueGenerationStrategy?value, bool fromDataAnnotation = false) { CheckValueGenerationStrategy(property, value); property.SetOrRemoveAnnotation(NpgsqlAnnotationNames.ValueGenerationStrategy, value, fromDataAnnotation); }
/// <summary> /// Sets the <see cref="NpgsqlValueGenerationStrategy" /> to use for the property. /// </summary> /// <param name="property">The property.</param> /// <param name="value">The strategy to use.</param> public static void SetValueGenerationStrategy( [NotNull] this IMutableProperty property, NpgsqlValueGenerationStrategy?value) { CheckValueGenerationStrategy(property, value); property.SetOrRemoveAnnotation(NpgsqlAnnotationNames.ValueGenerationStrategy, value); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public new virtual bool ValueGenerationStrategy(NpgsqlValueGenerationStrategy?value) { if (!SetValueGenerationStrategy(value)) { return(false); } switch (value) { case NpgsqlValueGenerationStrategy.SerialColumn: case NpgsqlValueGenerationStrategy.IdentityAlwaysColumn: case NpgsqlValueGenerationStrategy.IdentityByDefaultColumn: PropertyBuilder.ValueGenerated(ValueGenerated.OnAdd, ConfigurationSource.Convention); HiLoSequenceName(null); HiLoSequenceSchema(null); break; case NpgsqlValueGenerationStrategy.SequenceHiLo: PropertyBuilder.ValueGenerated(ValueGenerated.OnAdd, ConfigurationSource.Convention); break; case null: PropertyBuilder.ValueGenerated(ValueGenerated.Never, ConfigurationSource.Convention); HiLoSequenceName(null); HiLoSequenceSchema(null); break; default: throw new ArgumentException("Unknown NpgsqlValueGenerationStrategy value: " + value); } return(true); }
protected virtual bool SetValueGenerationStrategy(NpgsqlValueGenerationStrategy?value) { if (value != null) { var propertyType = Property.ClrType; if (value == NpgsqlValueGenerationStrategy.SerialColumn && !propertyType.IsIntegerForSerial()) { throw new ArgumentException($"Serial value generation cannot be used for the property '{Property.Name}' on entity type '{Property.DeclaringEntityType.DisplayName()}' because the property type is '{propertyType.ShortDisplayName()}'. Serial columns can only be of type short, int or long."); } if (value == NpgsqlValueGenerationStrategy.SequenceHiLo && !propertyType.IsInteger()) { throw new ArgumentException($"PostgreSQL sequences cannot be used to generate values for the property '{Property.Name}' on entity type '{Property.DeclaringEntityType.DisplayName()}' because the property type is '{propertyType.ShortDisplayName()}'. Sequences can only be used with integer properties."); } } if (!CanSetValueGenerationStrategy(value)) { return(false); } if (!ShouldThrowOnConflict && ValueGenerationStrategy != value && value != null) { ClearAllServerGeneratedValues(); } return(Annotations.SetAnnotation(NpgsqlFullAnnotationNames.Instance.ValueGenerationStrategy, null, value)); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public new virtual bool ValueGenerationStrategy(NpgsqlValueGenerationStrategy?value) { if (!SetValueGenerationStrategy(value)) { return(false); } if (value == null) { PropertyBuilder.ValueGenerated(ValueGenerated.Never, ConfigurationSource.Convention); HiLoSequenceName(null); HiLoSequenceSchema(null); } else if (value.Value == NpgsqlValueGenerationStrategy.SerialColumn) { PropertyBuilder.ValueGenerated(ValueGenerated.OnAdd, ConfigurationSource.Convention); HiLoSequenceName(null); HiLoSequenceSchema(null); } else if (value.Value == NpgsqlValueGenerationStrategy.SequenceHiLo) { PropertyBuilder.ValueGenerated(ValueGenerated.OnAdd, ConfigurationSource.Convention); } return(true); }
/// <summary> /// Attempts to set the <see cref="NpgsqlValueGenerationStrategy" /> to use for properties /// of keys in the model that don't have a strategy explicitly set. /// </summary> /// <param name="model"> The model. </param> /// <param name="value"> The value to set. </param> /// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param> public static NpgsqlValueGenerationStrategy?SetValueGenerationStrategy( this IConventionModel model, NpgsqlValueGenerationStrategy?value, bool fromDataAnnotation = false) { model.SetOrRemoveAnnotation(NpgsqlAnnotationNames.ValueGenerationStrategy, value, fromDataAnnotation); return(value); }
/// <summary> /// Returns a value indicating whether the given value can be set as the default value generation strategy. /// </summary> /// <param name="modelBuilder"> The model builder. </param> /// <param name="valueGenerationStrategy"> The value generation strategy. </param> /// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param> /// <returns> <c>true</c> if the given value can be set as the default value generation strategy. </returns> public static bool CanSetValueGenerationStrategy( this IConventionModelBuilder modelBuilder, NpgsqlValueGenerationStrategy?valueGenerationStrategy, bool fromDataAnnotation = false) { Check.NotNull(modelBuilder, nameof(modelBuilder)); return(modelBuilder.CanSetAnnotation( NpgsqlAnnotationNames.ValueGenerationStrategy, valueGenerationStrategy, fromDataAnnotation)); }
/// <summary> /// Returns a value indicating whether the given value can be set as the value generation strategy. /// </summary> /// <param name="propertyBuilder">The builder for the property being configured.</param> /// <param name="valueGenerationStrategy">The value generation strategy.</param> /// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param> /// <returns><c>true</c> if the given value can be set as the default value generation strategy.</returns> public static bool CanSetValueGenerationStrategy( [NotNull] this IConventionPropertyBuilder propertyBuilder, NpgsqlValueGenerationStrategy?valueGenerationStrategy, bool fromDataAnnotation = false) { Check.NotNull(propertyBuilder, nameof(propertyBuilder)); return((valueGenerationStrategy == null || NpgsqlPropertyExtensions.IsCompatibleWithValueGeneration(propertyBuilder.Metadata)) && propertyBuilder.CanSetAnnotation( NpgsqlAnnotationNames.ValueGenerationStrategy, valueGenerationStrategy, fromDataAnnotation)); }
/// <summary> /// Configures the value generation strategy for the key property, when targeting PostgreSQL. /// </summary> /// <param name="propertyBuilder">The builder for the property being configured.</param> /// <param name="valueGenerationStrategy">The value generation strategy.</param> /// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param> /// <returns> /// The same builder instance if the configuration was applied, <c>null</c> otherwise. /// </returns> public static IConventionPropertyBuilder HasValueGenerationStrategy( [NotNull] this IConventionPropertyBuilder propertyBuilder, NpgsqlValueGenerationStrategy?valueGenerationStrategy, bool fromDataAnnotation = false) { if (propertyBuilder.CanSetAnnotation( NpgsqlAnnotationNames.ValueGenerationStrategy, valueGenerationStrategy, fromDataAnnotation)) { propertyBuilder.Metadata.SetValueGenerationStrategy(valueGenerationStrategy, fromDataAnnotation); if (valueGenerationStrategy != NpgsqlValueGenerationStrategy.SequenceHiLo) { propertyBuilder.HasHiLoSequence(null, null, fromDataAnnotation); } return(propertyBuilder); } return(null); }
/// <summary> /// Configures the value generation strategy for the key property, when targeting PostgreSQL. /// </summary> /// <param name="modelBuilder">The builder for the property being configured.</param> /// <param name="valueGenerationStrategy">The value generation strategy.</param> /// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param> /// <returns> /// The same builder instance if the configuration was applied, <c>null</c> otherwise. /// </returns> public static IConventionModelBuilder?HasValueGenerationStrategy( this IConventionModelBuilder modelBuilder, NpgsqlValueGenerationStrategy?valueGenerationStrategy, bool fromDataAnnotation = false) { if (modelBuilder.CanSetAnnotation( NpgsqlAnnotationNames.ValueGenerationStrategy, valueGenerationStrategy, fromDataAnnotation)) { modelBuilder.Metadata.SetValueGenerationStrategy(valueGenerationStrategy, fromDataAnnotation); if (valueGenerationStrategy != NpgsqlValueGenerationStrategy.SequenceHiLo) { modelBuilder.HasHiLoSequence(null, null, fromDataAnnotation); } return(modelBuilder); } return(null); }
/// <inheritdoc /> public virtual void ProcessModelFinalizing( IConventionModelBuilder modelBuilder, IConventionContext <IConventionModelBuilder> context) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { foreach (var property in entityType.GetDeclaredProperties()) { NpgsqlValueGenerationStrategy?strategy = null; var table = entityType.GetTableName(); if (table != null) { var storeObject = StoreObjectIdentifier.Table(table, entityType.GetSchema()); strategy = property.GetValueGenerationStrategy(storeObject, Dependencies.TypeMappingSource); if (strategy == NpgsqlValueGenerationStrategy.None && !IsStrategyNoneNeeded(property, storeObject)) { strategy = null; } } else { var view = entityType.GetViewName(); if (view != null) { var storeObject = StoreObjectIdentifier.View(view, entityType.GetViewSchema()); strategy = property.GetValueGenerationStrategy(storeObject, Dependencies.TypeMappingSource); if (strategy == NpgsqlValueGenerationStrategy.None && !IsStrategyNoneNeeded(property, storeObject)) { strategy = null; } } } // Needed for the annotation to show up in the model snapshot if (strategy != null) { property.Builder.HasValueGenerationStrategy(strategy); } } }
protected virtual bool CanSetValueGenerationStrategy(NpgsqlValueGenerationStrategy?value) { if (GetNpgsqlValueGenerationStrategy(fallbackToModel: false) == value) { return(true); } if (!Annotations.CanSetAnnotation(NpgsqlFullAnnotationNames.Instance.ValueGenerationStrategy, null, value)) { return(false); } if (ShouldThrowOnConflict) { if (GetDefaultValue(false) != null) { throw new InvalidOperationException( RelationalStrings.ConflictingColumnServerGeneration(nameof(ValueGenerationStrategy), Property.Name, nameof(DefaultValue))); } if (GetDefaultValueSql(false) != null) { throw new InvalidOperationException( RelationalStrings.ConflictingColumnServerGeneration(nameof(ValueGenerationStrategy), Property.Name, nameof(DefaultValueSql))); } if (GetComputedColumnSql(false) != null) { throw new InvalidOperationException( RelationalStrings.ConflictingColumnServerGeneration(nameof(ValueGenerationStrategy), Property.Name, nameof(ComputedColumnSql))); } } else if (value != null && (!CanSetDefaultValue(null) || !CanSetDefaultValueSql(null) || !CanSetComputedColumnSql(null))) { return(false); } return(true); }
static void CheckValueGenerationStrategy(IProperty property, NpgsqlValueGenerationStrategy?value) { if (value != null) { var propertyType = property.ClrType; if (value == NpgsqlValueGenerationStrategy.SerialColumn && !propertyType.IsIntegerForValueGeneration()) { throw new ArgumentException($"Serial value generation cannot be used for the property '{property.Name}' on entity type '{property.DeclaringEntityType.DisplayName()}' because the property type is '{propertyType.ShortDisplayName()}'. Serial columns can only be of type short, int or long."); } if ((value == NpgsqlValueGenerationStrategy.IdentityAlwaysColumn || value == NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) && !propertyType.IsIntegerForValueGeneration()) { throw new ArgumentException($"Identity value generation cannot be used for the property '{property.Name}' on entity type '{property.DeclaringEntityType.DisplayName()}' because the property type is '{propertyType.ShortDisplayName()}'. Identity columns can only be of type short, int or long."); } if (value == NpgsqlValueGenerationStrategy.SequenceHiLo && !propertyType.IsInteger()) { throw new ArgumentException($"PostgreSQL sequences cannot be used to generate values for the property '{property.Name}' on entity type '{property.DeclaringEntityType.DisplayName()}' because the property type is '{propertyType.ShortDisplayName()}'. Sequences can only be used with integer properties."); } } }
/// <summary> /// Attempts to set the <see cref="NpgsqlValueGenerationStrategy" /> to use for properties /// of keys in the model that don't have a strategy explicitly set. /// </summary> /// <param name="model"> The model. </param> /// <param name="value"> The value to set. </param> /// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param> public static void SetValueGenerationStrategy( [NotNull] this IConventionModel model, NpgsqlValueGenerationStrategy?value, bool fromDataAnnotation = false) => model.SetOrRemoveAnnotation(NpgsqlAnnotationNames.ValueGenerationStrategy, value, fromDataAnnotation);
/// <summary> /// Attempts to set the <see cref="NpgsqlValueGenerationStrategy" /> to use for properties /// of keys in the model that don't have a strategy explicitly set. /// </summary> /// <param name="model"> The model. </param> /// <param name="value"> The value to set. </param> public static void SetValueGenerationStrategy(this IMutableModel model, NpgsqlValueGenerationStrategy?value) => model.SetOrRemoveAnnotation(NpgsqlAnnotationNames.ValueGenerationStrategy, value);
/// <inheritdoc /> public virtual void ProcessModelFinalizing( IConventionModelBuilder modelBuilder, IConventionContext <IConventionModelBuilder> context) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { foreach (var property in entityType.GetDeclaredProperties()) { NpgsqlValueGenerationStrategy?strategy = null; var table = entityType.GetTableName(); if (table is not null) { var storeObject = StoreObjectIdentifier.Table(table, entityType.GetSchema()); strategy = property.GetValueGenerationStrategy(storeObject, Dependencies.TypeMappingSource); if (strategy == NpgsqlValueGenerationStrategy.None && !IsStrategyNoneNeeded(property, storeObject)) { strategy = null; } } else { var view = entityType.GetViewName(); if (view is not null) { var storeObject = StoreObjectIdentifier.View(view, entityType.GetViewSchema()); strategy = property.GetValueGenerationStrategy(storeObject, Dependencies.TypeMappingSource); if (strategy == NpgsqlValueGenerationStrategy.None && !IsStrategyNoneNeeded(property, storeObject)) { strategy = null; } } } // Needed for the annotation to show up in the model snapshot if (strategy is not null) { property.Builder.HasValueGenerationStrategy(strategy); } } } bool IsStrategyNoneNeeded(IReadOnlyProperty property, StoreObjectIdentifier storeObject) { if (property.ValueGenerated == ValueGenerated.OnAdd && !property.TryGetDefaultValue(storeObject, out _) && property.GetDefaultValueSql(storeObject) is null && property.GetComputedColumnSql(storeObject) is null && property.DeclaringEntityType.Model.GetValueGenerationStrategy() != NpgsqlValueGenerationStrategy.None) { var providerClrType = (property.GetValueConverter() ?? (property.FindRelationalTypeMapping(storeObject) ?? Dependencies.TypeMappingSource.FindMapping((IProperty)property))?.Converter) ?.ProviderClrType.UnwrapNullableType(); return(providerClrType is not null && (providerClrType.IsInteger())); } return(false); } }
public static bool IsIdentity(this NpgsqlValueGenerationStrategy?strategy) => strategy == NpgsqlValueGenerationStrategy.IdentityByDefaultColumn || strategy == NpgsqlValueGenerationStrategy.IdentityAlwaysColumn;
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public new virtual bool ValueGenerationStrategy(NpgsqlValueGenerationStrategy?value) => SetValueGenerationStrategy(value);
protected virtual bool SetValueGenerationStrategy(NpgsqlValueGenerationStrategy?value) => Annotations.SetAnnotation(NpgsqlFullAnnotationNames.Instance.ValueGenerationStrategy, null, value);