diff --git a/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs index 90254052f1a..1d8964d40e8 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs @@ -807,7 +807,6 @@ internal static SqlServerValueGenerationStrategy GetValueGenerationStrategy( private static SqlServerValueGenerationStrategy GetDefaultValueGenerationStrategy(IReadOnlyProperty property) { var modelStrategy = property.DeclaringType.Model.GetValueGenerationStrategy(); - if (modelStrategy is SqlServerValueGenerationStrategy.SequenceHiLo or SqlServerValueGenerationStrategy.Sequence && IsCompatibleWithValueGeneration(property)) { @@ -826,7 +825,6 @@ private static SqlServerValueGenerationStrategy GetDefaultValueGenerationStrateg ITypeMappingSource? typeMappingSource) { var modelStrategy = property.DeclaringType.Model.GetValueGenerationStrategy(); - if (modelStrategy is SqlServerValueGenerationStrategy.SequenceHiLo or SqlServerValueGenerationStrategy.Sequence && IsCompatibleWithValueGeneration(property, storeObject, typeMappingSource)) { @@ -979,9 +977,9 @@ private static bool IsCompatibleWithValueGeneration( var type = (valueConverter?.ProviderClrType ?? property.ClrType).UnwrapNullableType(); - return (type.IsInteger() + return type.IsInteger() || type.IsEnum - || type == typeof(decimal)); + || type == typeof(decimal); } /// diff --git a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs index b7a201bed31..51021fa5c82 100644 --- a/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs +++ b/src/EFCore.SqlServer/Metadata/Conventions/SqlServerValueGenerationConvention.cs @@ -96,27 +96,24 @@ public override void ProcessEntityTypeAnnotationChanged( /// The store value generation strategy to set for the given property. protected override ValueGenerated? GetValueGenerated(IConventionProperty property) { - // TODO: move to relational? - if (property.DeclaringType.IsMappedToJson() + var table = property.GetMappedStoreObjects(StoreObjectType.Table).FirstOrDefault(); + return table.Name != null + ? GetValueGenerated(property, table, Dependencies.TypeMappingSource) + : property.DeclaringType.IsMappedToJson() #pragma warning disable EF1001 // Internal EF Core API usage. - && property.IsOrdinalKeyProperty() + && property.IsOrdinalKeyProperty() #pragma warning restore EF1001 // Internal EF Core API usage. - && (property.DeclaringType as IReadOnlyEntityType)?.FindOwnership()!.IsUnique == false) - { - return ValueGenerated.OnAdd; - } - - var declaringTable = property.GetMappedStoreObjects(StoreObjectType.Table).FirstOrDefault(); - if (declaringTable.Name == null) - { - return null; - } - - // If the first mapping can be value generated then we'll consider all mappings to be value generated - // as this is a client-side configuration and can't be specified per-table. - return GetValueGenerated(property, declaringTable, Dependencies.TypeMappingSource); + && (property.DeclaringType as IReadOnlyEntityType)?.FindOwnership()!.IsUnique == false + ? ValueGenerated.OnAddOrUpdate + : property.GetMappedStoreObjects(StoreObjectType.InsertStoredProcedure).Any() + ? GetValueGenerated((IReadOnlyProperty)property) + : null; } + /// + protected override bool MappingStrategyAllowsValueGeneration(IConventionProperty property, string? mappingStrategy) + => true; + /// /// Returns the store value generation strategy to set for the given property. /// diff --git a/src/EFCore.Sqlite.Core/Design/Internal/SqliteAnnotationCodeGenerator.cs b/src/EFCore.Sqlite.Core/Design/Internal/SqliteAnnotationCodeGenerator.cs new file mode 100644 index 00000000000..94af8624a0b --- /dev/null +++ b/src/EFCore.Sqlite.Core/Design/Internal/SqliteAnnotationCodeGenerator.cs @@ -0,0 +1,96 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using Microsoft.EntityFrameworkCore.Sqlite.Metadata.Internal; + +namespace Microsoft.EntityFrameworkCore.Sqlite.Design.Internal; + +/// +/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to +/// the same compatibility standards as public APIs. It may be changed or removed without notice in +/// any release. You should only use it directly in your code with extreme caution and knowing that +/// doing so can result in application failures when updating to a new Entity Framework Core release. +/// +public class SqliteAnnotationCodeGenerator : AnnotationCodeGenerator +{ + #region MethodInfos + + private static readonly MethodInfo PropertyUseAutoincrementMethodInfo + = typeof(SqlitePropertyBuilderExtensions).GetRuntimeMethod( + nameof(SqlitePropertyBuilderExtensions.UseAutoincrement), [typeof(PropertyBuilder)])!; + + private static readonly MethodInfo ComplexTypePropertyUseAutoincrementMethodInfo + = typeof(SqliteComplexTypePropertyBuilderExtensions).GetRuntimeMethod( + nameof(SqliteComplexTypePropertyBuilderExtensions.UseAutoincrement), [typeof(ComplexTypePropertyBuilder)])!; + + #endregion MethodInfos + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public SqliteAnnotationCodeGenerator(AnnotationCodeGeneratorDependencies dependencies) + : base(dependencies) + { + } + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public override IReadOnlyList GenerateFluentApiCalls( + IProperty property, + IDictionary annotations) + { + var fragments = new List(base.GenerateFluentApiCalls(property, annotations)); + + if (TryGetAndRemove(annotations, SqliteAnnotationNames.ValueGenerationStrategy, out var strategy) + && strategy == SqliteValueGenerationStrategy.Autoincrement) + { + var methodInfo = property.DeclaringType is IComplexType + ? ComplexTypePropertyUseAutoincrementMethodInfo + : PropertyUseAutoincrementMethodInfo; + fragments.Add(new MethodCallCodeFragment(methodInfo)); + } + + return fragments; + } + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + protected override bool IsHandledByConvention(IProperty property, IAnnotation annotation) + { + if (annotation.Name == SqliteAnnotationNames.ValueGenerationStrategy) + { + return (SqliteValueGenerationStrategy)annotation.Value! == property.GetDefaultValueGenerationStrategy(); + } + + return base.IsHandledByConvention(property, annotation); + } + + private static bool TryGetAndRemove( + IDictionary annotations, + string annotationName, + [NotNullWhen(true)] out T? annotationValue) + { + if (annotations.TryGetValue(annotationName, out var annotation) + && annotation.Value != null) + { + annotations.Remove(annotationName); + annotationValue = (T)annotation.Value; + return true; + } + + annotationValue = default; + return false; + } +} diff --git a/src/EFCore.Sqlite.Core/Design/Internal/SqliteDesignTimeServices.cs b/src/EFCore.Sqlite.Core/Design/Internal/SqliteDesignTimeServices.cs index 0ed5c42dfb4..9b40432265b 100644 --- a/src/EFCore.Sqlite.Core/Design/Internal/SqliteDesignTimeServices.cs +++ b/src/EFCore.Sqlite.Core/Design/Internal/SqliteDesignTimeServices.cs @@ -27,6 +27,7 @@ public virtual void ConfigureDesignTimeServices(IServiceCollection serviceCollec serviceCollection.AddEntityFrameworkSqlite(); #pragma warning disable EF1001 // Internal EF Core API usage. new EntityFrameworkRelationalDesignServicesBuilder(serviceCollection) + .TryAdd() .TryAdd() #pragma warning restore EF1001 // Internal EF Core API usage. .TryAdd() diff --git a/src/EFCore.Sqlite.Core/Diagnostics/ConflictingValueGenerationStrategiesEventData.cs b/src/EFCore.Sqlite.Core/Diagnostics/ConflictingValueGenerationStrategiesEventData.cs new file mode 100644 index 00000000000..400d2446688 --- /dev/null +++ b/src/EFCore.Sqlite.Core/Diagnostics/ConflictingValueGenerationStrategiesEventData.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Diagnostics; + +/// +/// A event payload class for events that have +/// conflicting value generation strategies. +/// +/// +/// See Logging, events, and diagnostics, and +/// Accessing SQLite databases with EF Core +/// for more information and examples. +/// +public class ConflictingValueGenerationStrategiesEventData : EventData +{ + /// + /// Constructs the event payload. + /// + /// The event definition. + /// A delegate that generates a log message for this event. + /// The SQLite value generation strategy. + /// The other value generation strategy. + /// The property. + public ConflictingValueGenerationStrategiesEventData( + EventDefinitionBase eventDefinition, + Func messageGenerator, + SqliteValueGenerationStrategy sqliteValueGenerationStrategy, + string otherValueGenerationStrategy, + IReadOnlyProperty property) + : base(eventDefinition, messageGenerator) + { + SqliteValueGenerationStrategy = sqliteValueGenerationStrategy; + OtherValueGenerationStrategy = otherValueGenerationStrategy; + Property = property; + } + + /// + /// The SQLite value generation strategy. + /// + public virtual SqliteValueGenerationStrategy SqliteValueGenerationStrategy { get; } + + /// + /// The other value generation strategy. + /// + public virtual string OtherValueGenerationStrategy { get; } + + /// + /// The property. + /// + public virtual IReadOnlyProperty Property { get; } +} \ No newline at end of file diff --git a/src/EFCore.Sqlite.Core/Diagnostics/Internal/SqliteLoggingDefinitions.cs b/src/EFCore.Sqlite.Core/Diagnostics/Internal/SqliteLoggingDefinitions.cs index 493c1b531de..dcca3a8e86c 100644 --- a/src/EFCore.Sqlite.Core/Diagnostics/Internal/SqliteLoggingDefinitions.cs +++ b/src/EFCore.Sqlite.Core/Diagnostics/Internal/SqliteLoggingDefinitions.cs @@ -131,6 +131,14 @@ public class SqliteLoggingDefinitions : RelationalLoggingDefinitions /// public EventDefinitionBase? LogCompositeKeyWithValueGeneration; + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public EventDefinitionBase? LogConflictingValueGenerationStrategies; + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in diff --git a/src/EFCore.Sqlite.Core/Diagnostics/SqliteEventId.cs b/src/EFCore.Sqlite.Core/Diagnostics/SqliteEventId.cs index a5c85d3b1ed..477ede53c99 100644 --- a/src/EFCore.Sqlite.Core/Diagnostics/SqliteEventId.cs +++ b/src/EFCore.Sqlite.Core/Diagnostics/SqliteEventId.cs @@ -30,6 +30,7 @@ private enum Id SchemaConfiguredWarning = CoreEventId.ProviderBaseId, SequenceConfiguredWarning, CompositeKeyWithValueGeneration, + ConflictingValueGenerationStrategiesWarning, // Infrastructure events UnexpectedConnectionTypeWarning = CoreEventId.ProviderBaseId + 100, @@ -98,6 +99,20 @@ private static EventId MakeValidationId(Id id) /// public static readonly EventId CompositeKeyWithValueGeneration = MakeValidationId(Id.CompositeKeyWithValueGeneration); + /// + /// Both the SqliteValueGenerationStrategy and another value generation configuration have been set on a property. + /// Configuring two strategies is usually unintentional and will likely result in a database error. + /// + /// + /// + /// This event is in the category. + /// + /// + /// This event uses the payload when used with a . + /// + /// + public static readonly EventId ConflictingValueGenerationStrategiesWarning = MakeValidationId(Id.ConflictingValueGenerationStrategiesWarning); + private static readonly string InfraPrefix = DbLoggerCategory.Infrastructure.Name + "."; private static EventId MakeInfraId(Id id) diff --git a/src/EFCore.Sqlite.Core/Extensions/Internal/SqliteLoggerExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/Internal/SqliteLoggerExtensions.cs index 99e3ad2f16a..dd1125ed14b 100644 --- a/src/EFCore.Sqlite.Core/Extensions/Internal/SqliteLoggerExtensions.cs +++ b/src/EFCore.Sqlite.Core/Extensions/Internal/SqliteLoggerExtensions.cs @@ -414,6 +414,51 @@ private static string CompositeKeyWithValueGeneration(EventDefinitionBase defini p.Key.Properties.Format()); } + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public static void ConflictingValueGenerationStrategiesWarning( + this IDiagnosticsLogger diagnostics, + SqliteValueGenerationStrategy sqliteValueGenerationStrategy, + string otherValueGenerationStrategy, + IReadOnlyProperty property) + { + var definition = SqliteResources.LogConflictingValueGenerationStrategies(diagnostics); + + if (diagnostics.ShouldLog(definition)) + { + definition.Log( + diagnostics, sqliteValueGenerationStrategy.ToString(), otherValueGenerationStrategy, + property.Name, property.DeclaringType.DisplayName()); + } + + if (diagnostics.NeedsEventData(definition, out var diagnosticSourceEnabled, out var simpleLogEnabled)) + { + var eventData = new ConflictingValueGenerationStrategiesEventData( + definition, + ConflictingValueGenerationStrategiesWarning, + sqliteValueGenerationStrategy, + otherValueGenerationStrategy, + property); + + diagnostics.DispatchEventData(definition, eventData, diagnosticSourceEnabled, simpleLogEnabled); + } + } + + private static string ConflictingValueGenerationStrategiesWarning(EventDefinitionBase definition, EventData payload) + { + var d = (EventDefinition)definition; + var p = (ConflictingValueGenerationStrategiesEventData)payload; + return d.GenerateMessage( + p.SqliteValueGenerationStrategy.ToString(), + p.OtherValueGenerationStrategy, + p.Property.Name, + p.Property.DeclaringType.DisplayName()); + } + /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in diff --git a/src/EFCore.Sqlite.Core/Extensions/SqliteComplexTypePropertyBuilderExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/SqliteComplexTypePropertyBuilderExtensions.cs index 17154e792eb..bd2e28ce5f5 100644 --- a/src/EFCore.Sqlite.Core/Extensions/SqliteComplexTypePropertyBuilderExtensions.cs +++ b/src/EFCore.Sqlite.Core/Extensions/SqliteComplexTypePropertyBuilderExtensions.cs @@ -12,6 +12,37 @@ namespace Microsoft.EntityFrameworkCore; /// public static class SqliteComplexTypePropertyBuilderExtensions { + /// + /// Configures the property to use the SQLite AUTOINCREMENT feature to generate values for new entities, + /// when targeting SQLite. This method sets the property's value generation strategy to . + /// + /// + /// See Modeling entity types and relationships, and + /// Accessing SQLite databases with EF Core for more information and examples. + /// + /// The builder for the property being configured. + /// The same builder instance so that multiple calls can be chained. + public static ComplexTypePropertyBuilder UseAutoincrement(this ComplexTypePropertyBuilder propertyBuilder) + { + propertyBuilder.Metadata.SetValueGenerationStrategy(SqliteValueGenerationStrategy.Autoincrement); + + return propertyBuilder; + } + + /// + /// Configures the property to use the SQLite AUTOINCREMENT feature to generate values for new entities, + /// when targeting SQLite. This method sets the property's value generation strategy to . + /// + /// + /// See Modeling entity types and relationships, and + /// Accessing SQLite databases with EF Core for more information and examples. + /// + /// The builder for the property being configured. + /// The same builder instance so that multiple calls can be chained. + public static ComplexTypePropertyBuilder UseAutoincrement( + this ComplexTypePropertyBuilder propertyBuilder) + => (ComplexTypePropertyBuilder)UseAutoincrement((ComplexTypePropertyBuilder)propertyBuilder); + /// /// Configures the SRID of the column that the property maps to when targeting SQLite. /// diff --git a/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyBuilderExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyBuilderExtensions.cs index a70174eddec..34bf3093814 100644 --- a/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyBuilderExtensions.cs +++ b/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyBuilderExtensions.cs @@ -15,6 +15,97 @@ namespace Microsoft.EntityFrameworkCore; /// public static class SqlitePropertyBuilderExtensions { + /// + /// Configures the property to use SQLite AUTOINCREMENT feature to generate values for new entities, + /// when targeting SQLite. This method sets the property to be . + /// + /// + /// AUTOINCREMENT can only be used on integer primary key columns in SQLite. + /// See Modeling entity types and relationships, and + /// Accessing SQLite databases with EF Core for more information and examples. + /// + /// The builder for the property being configured. + /// The same builder instance so that multiple calls can be chained. + public static PropertyBuilder UseAutoincrement(this PropertyBuilder propertyBuilder) + { + propertyBuilder.Metadata.SetValueGenerationStrategy(SqliteValueGenerationStrategy.Autoincrement); + + return propertyBuilder; + } + + /// + /// Configures the property to use SQLite AUTOINCREMENT feature to generate values for new entities, + /// when targeting SQLite. This method sets the property to be . + /// + /// + /// AUTOINCREMENT can only be used on integer primary key columns in SQLite. + /// See Modeling entity types and relationships, and + /// Accessing SQLite databases with EF Core for more information and examples. + /// + /// The type of the property being configured. + /// The builder for the property being configured. + /// The same builder instance so that multiple calls can be chained. + public static PropertyBuilder UseAutoincrement( + this PropertyBuilder propertyBuilder) + => (PropertyBuilder)UseAutoincrement((PropertyBuilder)propertyBuilder); + + /// + /// Configures the property to use SQLite AUTOINCREMENT feature to generate values for new entities, + /// when targeting SQLite. This method sets the property to be . + /// + /// + /// AUTOINCREMENT can only be used on integer primary key columns in SQLite. + /// See Modeling entity types and relationships, and + /// Accessing SQLite databases with EF Core for more information and examples. + /// + /// The builder for the column being configured. + /// The same builder instance so that multiple calls can be chained. + public static ColumnBuilder UseAutoincrement( + this ColumnBuilder columnBuilder) + { + columnBuilder.Overrides.SetValueGenerationStrategy(SqliteValueGenerationStrategy.Autoincrement); + + return columnBuilder; + } + + /// + /// Configures the value generation strategy for the property when targeting SQLite. + /// + /// The builder for the property being configured. + /// The strategy to use. + /// Indicates whether the configuration was specified using a data annotation. + /// + /// The same builder instance if the configuration was applied, + /// otherwise. + /// + public static IConventionPropertyBuilder? HasValueGenerationStrategy( + this IConventionPropertyBuilder propertyBuilder, + SqliteValueGenerationStrategy? strategy, + bool fromDataAnnotation = false) + { + if (propertyBuilder.CanSetValueGenerationStrategy(strategy, fromDataAnnotation)) + { + propertyBuilder.Metadata.SetValueGenerationStrategy(strategy, fromDataAnnotation); + return propertyBuilder; + } + + return null; + } + + /// + /// Returns a value indicating whether the given value generation strategy can be set for the property. + /// + /// The builder for the property. + /// The strategy. + /// Indicates whether the configuration was specified using a data annotation. + /// if the given value generation strategy can be set for the property. + public static bool CanSetValueGenerationStrategy( + this IConventionPropertyBuilder propertyBuilder, + SqliteValueGenerationStrategy? strategy, + bool fromDataAnnotation = false) + => propertyBuilder.CanSetAnnotation( + SqliteAnnotationNames.ValueGenerationStrategy, strategy, fromDataAnnotation); + /// /// Configures the SRID of the column that the property maps to when targeting SQLite. /// diff --git a/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs index bcf0b3815fb..85d03995660 100644 --- a/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs +++ b/src/EFCore.Sqlite.Core/Extensions/SqlitePropertyExtensions.cs @@ -15,6 +15,229 @@ namespace Microsoft.EntityFrameworkCore; /// public static class SqlitePropertyExtensions { + /// + /// Returns the to use for the property. + /// + /// The property. + /// The strategy to use for the property. + public static SqliteValueGenerationStrategy GetValueGenerationStrategy(this IReadOnlyProperty property) + => property[SqliteAnnotationNames.ValueGenerationStrategy] is SqliteValueGenerationStrategy strategy + ? strategy + : property.GetDefaultValueGenerationStrategy(); + + /// + /// Returns the to use for the property. + /// + /// + /// If no strategy is set for the property, then the strategy to use will be taken from the . + /// + /// The property overrides. + /// The strategy, or if none was set. + public static SqliteValueGenerationStrategy? GetValueGenerationStrategy( + this IReadOnlyRelationalPropertyOverrides overrides) + => (SqliteValueGenerationStrategy?)overrides.FindAnnotation(SqliteAnnotationNames.ValueGenerationStrategy) + ?.Value; + + /// + /// Returns the to use for the property. + /// + /// The property. + /// The identifier of the store object. + /// The strategy to use for the property. + public static SqliteValueGenerationStrategy GetValueGenerationStrategy( + this IReadOnlyProperty property, + in StoreObjectIdentifier storeObject) + => GetValueGenerationStrategy(property, storeObject, null); + + /// + /// Returns the default to use for the property. + /// + /// The property. + /// The default strategy for the property. + public static SqliteValueGenerationStrategy GetDefaultValueGenerationStrategy(this IReadOnlyProperty property) + => GetDefaultValueGenerationStrategyInternal(property, property.FindRelationalTypeMapping()); + + internal static SqliteValueGenerationStrategy GetValueGenerationStrategy( + this IReadOnlyProperty property, + in StoreObjectIdentifier storeObject, + ITypeMappingSource? typeMappingSource) + { + var @override = property.FindOverrides(storeObject)?.FindAnnotation(SqliteAnnotationNames.ValueGenerationStrategy); + if (@override != null) + { + return (SqliteValueGenerationStrategy?)@override.Value ?? SqliteValueGenerationStrategy.None; + } + + var annotation = property.FindAnnotation(SqliteAnnotationNames.ValueGenerationStrategy); + if (annotation?.Value != null + && StoreObjectIdentifier.Create(property.DeclaringType, storeObject.StoreObjectType) == storeObject) + { + return (SqliteValueGenerationStrategy)annotation.Value; + } + + var table = storeObject; + var sharedProperty = property.FindSharedStoreObjectRootProperty(storeObject); + return sharedProperty != null + ? sharedProperty.GetValueGenerationStrategy(storeObject, typeMappingSource) == SqliteValueGenerationStrategy.Autoincrement + && storeObject.StoreObjectType == StoreObjectType.Table + && !property.GetContainingForeignKeys().Any(fk => + !fk.IsBaseLinking() + || (StoreObjectIdentifier.Create(fk.PrincipalEntityType, StoreObjectType.Table) + is { } principal + && fk.GetConstraintName(table, principal) != null)) + ? SqliteValueGenerationStrategy.Autoincrement + : SqliteValueGenerationStrategy.None + : GetDefaultValueGenerationStrategy(property, storeObject, typeMappingSource); + } + + private static SqliteValueGenerationStrategy GetDefaultValueGenerationStrategy( + IReadOnlyProperty property, + in StoreObjectIdentifier storeObject, + ITypeMappingSource? typeMappingSource) + { + if (storeObject.StoreObjectType != StoreObjectType.Table + || property.IsForeignKey() + || property.ValueGenerated == ValueGenerated.Never + || property.DeclaringType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy) + { + return SqliteValueGenerationStrategy.None; + } + + return GetDefaultValueGenerationStrategyInternal(property, property.FindRelationalTypeMapping(storeObject)); + } + + private static SqliteValueGenerationStrategy GetDefaultValueGenerationStrategyInternal( + IReadOnlyProperty property, + RelationalTypeMapping? typeMapping) + { + if (property.TryGetDefaultValue(out _) + || property.GetDefaultValueSql() != null + || property.GetComputedColumnSql() != null + || property.IsForeignKey() + || property.ValueGenerated == ValueGenerated.Never + || property.DeclaringType.GetMappingStrategy() == RelationalAnnotationNames.TpcMappingStrategy) + { + return SqliteValueGenerationStrategy.None; + } + + var primaryKey = property.DeclaringType.ContainingEntityType.FindPrimaryKey(); + if (primaryKey is not { Properties.Count: 1 } + || primaryKey.Properties[0] != property + || !property.ClrType.UnwrapNullableType().IsInteger() + || (typeMapping?.Converter?.ProviderClrType + ?? typeMapping?.ClrType)?.IsInteger() != true) + { + return SqliteValueGenerationStrategy.None; + } + + return SqliteValueGenerationStrategy.Autoincrement; + } + + /// + /// Sets the to use for the property. + /// + /// The property. + /// The strategy to use. + public static void SetValueGenerationStrategy( + this IMutableProperty property, + SqliteValueGenerationStrategy? value) + => property.SetOrRemoveAnnotation(SqliteAnnotationNames.ValueGenerationStrategy, value); + + /// + /// Sets the to use for the property. + /// + /// The property. + /// The strategy to use. + /// Indicates whether the configuration was specified using a data annotation. + /// The configured value. + public static SqliteValueGenerationStrategy? SetValueGenerationStrategy( + this IConventionProperty property, + SqliteValueGenerationStrategy? value, + bool fromDataAnnotation = false) + => (SqliteValueGenerationStrategy?)property.SetOrRemoveAnnotation( + SqliteAnnotationNames.ValueGenerationStrategy, value, fromDataAnnotation)?.Value; + + /// + /// Sets the to use for the property for a particular table. + /// + /// The property. + /// The strategy to use. + /// The identifier of the table containing the column. + public static void SetValueGenerationStrategy( + this IMutableProperty property, + SqliteValueGenerationStrategy? value, + in StoreObjectIdentifier storeObject) + => property.GetOrCreateOverrides(storeObject) + .SetValueGenerationStrategy(value); + + /// + /// Sets the to use for the property for a particular table. + /// + /// The property. + /// The strategy to use. + /// The identifier of the table containing the column. + /// Indicates whether the configuration was specified using a data annotation. + /// The configured value. + public static SqliteValueGenerationStrategy? SetValueGenerationStrategy( + this IConventionProperty property, + SqliteValueGenerationStrategy? value, + in StoreObjectIdentifier storeObject, + bool fromDataAnnotation = false) + => property.GetOrCreateOverrides(storeObject, fromDataAnnotation) + .SetValueGenerationStrategy(value, fromDataAnnotation); + + /// + /// Sets the to use for the property for a particular table. + /// + /// The property overrides. + /// The strategy to use. + public static void SetValueGenerationStrategy( + this IMutableRelationalPropertyOverrides overrides, + SqliteValueGenerationStrategy? value) + => overrides.SetOrRemoveAnnotation(SqliteAnnotationNames.ValueGenerationStrategy, value); + + /// + /// Sets the to use for the property for a particular table. + /// + /// The property overrides. + /// The strategy to use. + /// Indicates whether the configuration was specified using a data annotation. + /// The configured value. + public static SqliteValueGenerationStrategy? SetValueGenerationStrategy( + this IConventionRelationalPropertyOverrides overrides, + SqliteValueGenerationStrategy? value, + bool fromDataAnnotation = false) + => (SqliteValueGenerationStrategy?)overrides.SetOrRemoveAnnotation( + SqliteAnnotationNames.ValueGenerationStrategy, value, fromDataAnnotation)?.Value; + + /// + /// Gets the for the value generation strategy. + /// + /// The property. + /// The for the value generation strategy. + public static ConfigurationSource? GetValueGenerationStrategyConfigurationSource(this IConventionProperty property) + => property.FindAnnotation(SqliteAnnotationNames.ValueGenerationStrategy)?.GetConfigurationSource(); + + /// + /// Returns the for the for a particular table. + /// + /// The property. + /// The identifier of the table containing the column. + /// The for the . + public static ConfigurationSource? GetValueGenerationStrategyConfigurationSource( + this IConventionProperty property, + in StoreObjectIdentifier storeObject) + => property.FindOverrides(storeObject)?.GetValueGenerationStrategyConfigurationSource(); + + /// + /// Returns the for the for a particular table. + /// + /// The property overrides. + /// The for the . + public static ConfigurationSource? GetValueGenerationStrategyConfigurationSource( + this IConventionRelationalPropertyOverrides overrides) + => overrides.FindAnnotation(SqliteAnnotationNames.ValueGenerationStrategy)?.GetConfigurationSource(); + /// /// Returns the SRID to use when creating a column for this property. /// diff --git a/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteConventionSetBuilder.cs b/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteConventionSetBuilder.cs index 1cebd484d5b..d84a94fbeb4 100644 --- a/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteConventionSetBuilder.cs +++ b/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteConventionSetBuilder.cs @@ -45,6 +45,8 @@ public override ConventionSet CreateConventionSet() conventionSet.Replace(new SqliteSharedTableConvention(Dependencies, RelationalDependencies)); conventionSet.Replace(new SqliteRuntimeModelConvention(Dependencies, RelationalDependencies)); + conventionSet.Replace(new SqliteValueGenerationConvention(Dependencies, RelationalDependencies)); + conventionSet.Replace(new SqliteStoreGenerationConvention(Dependencies, RelationalDependencies)); return conventionSet; } diff --git a/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteStoreGenerationConvention.cs b/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteStoreGenerationConvention.cs new file mode 100644 index 00000000000..18dda3c7b5b --- /dev/null +++ b/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteStoreGenerationConvention.cs @@ -0,0 +1,131 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.Sqlite.Internal; +using Microsoft.EntityFrameworkCore.Sqlite.Metadata.Internal; + +// ReSharper disable once CheckNamespace +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; + +/// +/// A convention that ensures that properties aren't configured to have a default value, as computed column +/// or using a at the same time. +/// +/// +/// See Model building conventions, and +/// Accessing SQLite databases with EF Core +/// for more information and examples. +/// +public class SqliteStoreGenerationConvention : StoreGenerationConvention +{ + /// + /// Creates a new instance of . + /// + /// Parameter object containing dependencies for this convention. + /// Parameter object containing relational dependencies for this convention. + public SqliteStoreGenerationConvention( + ProviderConventionSetBuilderDependencies dependencies, + RelationalConventionSetBuilderDependencies relationalDependencies) + : base(dependencies, relationalDependencies) + { + } + + /// + /// Called after an annotation is changed on a property. + /// + /// The builder for the property. + /// The annotation name. + /// The new annotation. + /// The old annotation. + /// Additional information associated with convention execution. + public override void ProcessPropertyAnnotationChanged( + IConventionPropertyBuilder propertyBuilder, + string name, + IConventionAnnotation? annotation, + IConventionAnnotation? oldAnnotation, + IConventionContext context) + { + if (annotation == null + || oldAnnotation?.Value != null) + { + return; + } + + var configurationSource = annotation.GetConfigurationSource(); + var fromDataAnnotation = configurationSource != ConfigurationSource.Convention; + switch (name) + { + case RelationalAnnotationNames.DefaultValue: + if (propertyBuilder.HasValueGenerationStrategy(null, fromDataAnnotation) == null + && propertyBuilder.HasDefaultValue(null, fromDataAnnotation) != null) + { + context.StopProcessing(); + return; + } + + break; + case RelationalAnnotationNames.DefaultValueSql: + if (propertyBuilder.HasValueGenerationStrategy(null, fromDataAnnotation) == null + && propertyBuilder.HasDefaultValueSql(null, fromDataAnnotation) != null) + { + context.StopProcessing(); + return; + } + + break; + case RelationalAnnotationNames.ComputedColumnSql: + if (propertyBuilder.HasValueGenerationStrategy(null, fromDataAnnotation) == null + && propertyBuilder.HasComputedColumnSql(null, fromDataAnnotation) != null) + { + context.StopProcessing(); + return; + } + + break; + case SqliteAnnotationNames.ValueGenerationStrategy: + if ((propertyBuilder.HasDefaultValue(null, fromDataAnnotation) == null + || propertyBuilder.HasDefaultValueSql(null, fromDataAnnotation) == null + || propertyBuilder.HasComputedColumnSql(null, fromDataAnnotation) == null) + && propertyBuilder.HasValueGenerationStrategy(null, fromDataAnnotation) != null) + { + context.StopProcessing(); + return; + } + + break; + } + + base.ProcessPropertyAnnotationChanged(propertyBuilder, name, annotation, oldAnnotation, context); + } + + /// + protected override void Validate(IConventionProperty property, in StoreObjectIdentifier storeObject) + { + if (property.GetValueGenerationStrategyConfigurationSource() != null) + { + var generationStrategy = property.GetValueGenerationStrategy(storeObject); + if (generationStrategy != SqliteValueGenerationStrategy.None) + { + if (property.TryGetDefaultValue(storeObject, out _)) + { + Dependencies.ValidationLogger.ConflictingValueGenerationStrategiesWarning( + generationStrategy, "DefaultValue", property); + } + + if (property.GetDefaultValueSql(storeObject) != null) + { + Dependencies.ValidationLogger.ConflictingValueGenerationStrategiesWarning( + generationStrategy, "DefaultValueSql", property); + } + + if (property.GetComputedColumnSql(storeObject) != null) + { + Dependencies.ValidationLogger.ConflictingValueGenerationStrategiesWarning( + generationStrategy, "ComputedColumnSql", property); + } + } + } + + base.Validate(property, storeObject); + } +} \ No newline at end of file diff --git a/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteValueGenerationConvention.cs b/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteValueGenerationConvention.cs new file mode 100644 index 00000000000..d872b81c2fe --- /dev/null +++ b/src/EFCore.Sqlite.Core/Metadata/Conventions/SqliteValueGenerationConvention.cs @@ -0,0 +1,91 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Sqlite.Metadata.Internal; + +// ReSharper disable once CheckNamespace + +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions; + +/// +/// A convention that configures store value generation as on properties that are +/// part of the primary key and not part of any foreign keys, were configured to have a database default value +/// or were configured to use a . +/// It also configures properties as if they were configured as computed columns. +/// +/// +/// See Model building conventions, and +/// Accessing SQLite databases with EF Core +/// for more information and examples. +/// +public class SqliteValueGenerationConvention : RelationalValueGenerationConvention +{ + /// + /// Creates a new instance of . + /// + /// Parameter object containing dependencies for this convention. + /// Parameter object containing relational dependencies for this convention. + public SqliteValueGenerationConvention( + ProviderConventionSetBuilderDependencies dependencies, + RelationalConventionSetBuilderDependencies relationalDependencies) + : base(dependencies, relationalDependencies) + { + } + + /// + /// Called after an annotation is changed on a property. + /// + /// The builder for the property. + /// The annotation name. + /// The new annotation. + /// The old annotation. + /// Additional information associated with convention execution. + public override void ProcessPropertyAnnotationChanged( + IConventionPropertyBuilder propertyBuilder, + string name, + IConventionAnnotation? annotation, + IConventionAnnotation? oldAnnotation, + IConventionContext context) + { + if (name == SqliteAnnotationNames.ValueGenerationStrategy) + { + propertyBuilder.ValueGenerated(GetValueGenerated(propertyBuilder.Metadata)); + return; + } + + base.ProcessPropertyAnnotationChanged(propertyBuilder, name, annotation, oldAnnotation, context); + } + + /// + /// Returns the store value generation strategy to set for the given property. + /// + /// The property. + /// The store value generation strategy to set for the given property. + protected override ValueGenerated? GetValueGenerated(IConventionProperty property) + { + var table = property.GetMappedStoreObjects(StoreObjectType.Table).FirstOrDefault(); + return !MappingStrategyAllowsValueGeneration(property, property.DeclaringType.GetMappingStrategy()) + ? null + : table.Name != null + ? GetValueGenerated(property, table, Dependencies.TypeMappingSource) + : property.DeclaringType.IsMappedToJson() +#pragma warning disable EF1001 // Internal EF Core API usage. + && property.IsOrdinalKeyProperty() +#pragma warning restore EF1001 // Internal EF Core API usage. + && (property.DeclaringType as IReadOnlyEntityType)?.FindOwnership()!.IsUnique == false + ? ValueGenerated.OnAddOrUpdate + : property.GetMappedStoreObjects(StoreObjectType.InsertStoredProcedure).Any() + ? GetValueGenerated((IReadOnlyProperty)property) + : null; + } + + private static ValueGenerated? GetValueGenerated( + IReadOnlyProperty property, + in StoreObjectIdentifier storeObject, + ITypeMappingSource typeMappingSource) + => GetValueGenerated(property, storeObject) + ?? (property.GetValueGenerationStrategy(storeObject, typeMappingSource) != SqliteValueGenerationStrategy.None + ? ValueGenerated.OnAdd + : null); +} diff --git a/src/EFCore.Sqlite.Core/Metadata/Internal/SqliteAnnotationNames.cs b/src/EFCore.Sqlite.Core/Metadata/Internal/SqliteAnnotationNames.cs index 6e74bb68d4e..e6c7b56b181 100644 --- a/src/EFCore.Sqlite.Core/Metadata/Internal/SqliteAnnotationNames.cs +++ b/src/EFCore.Sqlite.Core/Metadata/Internal/SqliteAnnotationNames.cs @@ -74,4 +74,12 @@ public static class SqliteAnnotationNames /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public const string UseSqlReturningClause = Prefix + "UseSqlReturningClause"; + + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public const string ValueGenerationStrategy = Prefix + "ValueGenerationStrategy"; } diff --git a/src/EFCore.Sqlite.Core/Metadata/Internal/SqliteAnnotationProvider.cs b/src/EFCore.Sqlite.Core/Metadata/Internal/SqliteAnnotationProvider.cs index 525780bb16a..bb8376cb1d0 100644 --- a/src/EFCore.Sqlite.Core/Metadata/Internal/SqliteAnnotationProvider.cs +++ b/src/EFCore.Sqlite.Core/Metadata/Internal/SqliteAnnotationProvider.cs @@ -65,13 +65,8 @@ public override IEnumerable For(IColumn column, bool designTime) // Model validation ensures that these facets are the same on all mapped properties var property = column.PropertyMappings.First().Property; - // Only return auto increment for integer single column primary key - var primaryKey = property.DeclaringType.ContainingEntityType.FindPrimaryKey(); - if (primaryKey is { Properties.Count: 1 } - && primaryKey.Properties[0] == property - && property.ValueGenerated == ValueGenerated.OnAdd - && property.ClrType.UnwrapNullableType().IsInteger() - && !HasConverter(property)) + + if (property.GetValueGenerationStrategy() == SqliteValueGenerationStrategy.Autoincrement) { yield return new Annotation(SqliteAnnotationNames.Autoincrement, true); } @@ -82,7 +77,4 @@ public override IEnumerable For(IColumn column, bool designTime) yield return new Annotation(SqliteAnnotationNames.Srid, srid); } } - - private static bool HasConverter(IProperty property) - => property.FindTypeMapping()?.Converter != null; } diff --git a/src/EFCore.Sqlite.Core/Metadata/SqliteValueGenerationStrategy.cs b/src/EFCore.Sqlite.Core/Metadata/SqliteValueGenerationStrategy.cs new file mode 100644 index 00000000000..147fd163ca3 --- /dev/null +++ b/src/EFCore.Sqlite.Core/Metadata/SqliteValueGenerationStrategy.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// ReSharper disable once CheckNamespace + +namespace Microsoft.EntityFrameworkCore.Metadata; + +/// +/// Defines strategies to use across the EF Core stack when generating key values +/// from SQLite database columns. +/// +/// +/// See Model building conventions, and +/// Accessing SQLite databases with EF Core +/// for more information and examples. +/// +public enum SqliteValueGenerationStrategy +{ + /// + /// No SQLite-specific strategy + /// + None, + + /// + /// A pattern that uses SQLite's AUTOINCREMENT feature to generate values for new entities. + /// + /// + /// AUTOINCREMENT can only be used on integer primary key columns in SQLite. + /// + Autoincrement +} \ No newline at end of file diff --git a/src/EFCore.Sqlite.Core/Properties/SqliteStrings.Designer.cs b/src/EFCore.Sqlite.Core/Properties/SqliteStrings.Designer.cs index 8134f15a665..e07ab03354b 100644 --- a/src/EFCore.Sqlite.Core/Properties/SqliteStrings.Designer.cs +++ b/src/EFCore.Sqlite.Core/Properties/SqliteStrings.Designer.cs @@ -37,12 +37,6 @@ public static string AggregateOperationNotSupported(object? aggregateOperator, o public static string ApplyNotSupported => GetString("ApplyNotSupported"); - /// - /// ExecuteUpdate partial updates of ulong properties within JSON columns is not supported. - /// - public static string ExecuteUpdateJsonPartialUpdateDoesNotSupportUlong - => GetString("ExecuteUpdateJsonPartialUpdateDoesNotSupportUlong"); - /// /// Translating this operation requires the 'DEFAULT' keyword, which is not supported on SQLite. /// @@ -57,6 +51,12 @@ public static string DuplicateColumnNameSridMismatch(object? entityType1, object GetString("DuplicateColumnNameSridMismatch", nameof(entityType1), nameof(property1), nameof(entityType2), nameof(property2), nameof(columnName), nameof(table)), entityType1, property1, entityType2, property2, columnName, table); + /// + /// ExecuteUpdate partial updates of ulong properties within JSON columns is not supported. + /// + public static string ExecuteUpdateJsonPartialUpdateDoesNotSupportUlong + => GetString("ExecuteUpdateJsonPartialUpdateDoesNotSupportUlong"); + /// /// Table '{table}' cannot be used for entity type '{entityType}' since it is being used for entity type '{otherEntityType}' and entity type '{entityTypeWithSqlReturningClause}' is configured to use the SQL RETURNING clause, but entity type '{entityTypeWithoutSqlReturningClause}' is not. /// @@ -160,6 +160,31 @@ private static readonly ResourceManager _resourceManager return (EventDefinition)definition; } + /// + /// Both the SqliteValueGenerationStrategy '{generationStrategy}' and '{otherGenerationStrategy}' have been set on property '{propertyName}' on entity type '{entityName}'. Configuring two strategies is usually unintentional and will likely result in a database error. + /// + public static EventDefinition LogConflictingValueGenerationStrategies(IDiagnosticsLogger logger) + { + var definition = ((Diagnostics.Internal.SqliteLoggingDefinitions)logger.Definitions).LogConflictingValueGenerationStrategies; + if (definition == null) + { + definition = NonCapturingLazyInitializer.EnsureInitialized( + ref ((Diagnostics.Internal.SqliteLoggingDefinitions)logger.Definitions).LogConflictingValueGenerationStrategies, + logger, + static logger => new EventDefinition( + logger.Options, + SqliteEventId.ConflictingValueGenerationStrategiesWarning, + LogLevel.Warning, + "SqliteEventId.ConflictingValueGenerationStrategiesWarning", + level => LoggerMessage.Define( + level, + SqliteEventId.ConflictingValueGenerationStrategiesWarning, + _resourceManager.GetString("LogConflictingValueGenerationStrategies")!))); + } + + return (EventDefinition)definition; + } + /// /// Skipping foreign key with identity '{id}' on table '{tableName}' since principal table '{principalTableName}' was not found in the model. This usually happens when the principal table was not included in the selection set. /// diff --git a/src/EFCore.Sqlite.Core/Properties/SqliteStrings.resx b/src/EFCore.Sqlite.Core/Properties/SqliteStrings.resx index 0de1798a21f..fa65f8c5f41 100644 --- a/src/EFCore.Sqlite.Core/Properties/SqliteStrings.resx +++ b/src/EFCore.Sqlite.Core/Properties/SqliteStrings.resx @@ -123,15 +123,15 @@ Translating this query requires the SQL APPLY operation, which is not supported on SQLite. - - ExecuteUpdate partial updates of ulong properties within JSON columns is not supported. - Translating this operation requires the 'DEFAULT' keyword, which is not supported on SQLite. '{entityType1}.{property1}' and '{entityType2}.{property2}' are both mapped to column '{columnName}' in '{table}', but are configured with different SRIDs. + + ExecuteUpdate partial updates of ulong properties within JSON columns is not supported. + Table '{table}' cannot be used for entity type '{entityType}' since it is being used for entity type '{otherEntityType}' and entity type '{entityTypeWithSqlReturningClause}' is configured to use the SQL RETURNING clause, but entity type '{entityTypeWithoutSqlReturningClause}' is not. @@ -142,6 +142,10 @@ The entity type '{entityType}' has composite key '{key}' which is configured to use generated values. SQLite does not support generated values on composite keys. Warning SqliteEventId.CompositeKeyWithValueGeneration string? string? + + Both the SqliteValueGenerationStrategy '{generationStrategy}' and '{otherGenerationStrategy}' have been set on property '{propertyName}' on entity type '{entityName}'. Configuring two strategies is usually unintentional and will likely result in a database error. + Warning SqliteEventId.ConflictingValueGenerationStrategiesWarning string string string string + Skipping foreign key with identity '{id}' on table '{tableName}' since principal table '{principalTableName}' was not found in the model. This usually happens when the principal table was not included in the selection set. Warning SqliteEventId.ForeignKeyReferencesMissingTableWarning string? string? string? diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorSqliteTest.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorSqliteTest.cs new file mode 100644 index 00000000000..c7249420b52 --- /dev/null +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorSqliteTest.cs @@ -0,0 +1,189 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.Design.Internal; +using Microsoft.EntityFrameworkCore.Sqlite.Design.Internal; +using Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal; +using NetTopologySuite; + +namespace Microsoft.EntityFrameworkCore.Migrations.Design; + +public class CSharpMigrationsGeneratorSqliteTest : CSharpMigrationsGeneratorTestBase +{ + protected virtual string AddBoilerPlate(string code, bool usingSystem = false, bool usingMetadata = true) + => $$""" +// +{{(usingSystem + ? @"using System; +" + : "")}}using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +{{(usingMetadata + ? @"using Microsoft.EntityFrameworkCore.Metadata; +" + : "")}}using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace RootNamespace +{ + [DbContext(typeof(DbContext))] + partial class Snapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasDefaultSchema("DefaultSchema"); + +{{code}} +#pragma warning restore 612, 618 + } + } +} + +"""; + + [ConditionalFact] + public void Autoincrement_annotation_is_replaced_by_extension_method_call_in_snapshot() + { + Test( + builder => + { + builder.Entity(e => + { + e.Property(p => p.Id).UseAutoincrement(); + }); + }, + AddBoilerPlate(""" + modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTestBase+EntityWithAutoincrement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + SqlitePropertyBuilderExtensions.UseAutoincrement(b.Property("Id")); + + b.HasKey("Id"); + + b.ToTable("EntityWithAutoincrement", "DefaultSchema"); + }); + """), + model => + { + var entity = model.FindEntityType(typeof(EntityWithAutoincrement)); + var property = entity!.FindProperty("Id"); + Assert.Equal(SqliteValueGenerationStrategy.Autoincrement, Microsoft.EntityFrameworkCore.SqlitePropertyExtensions.GetValueGenerationStrategy(property!)); + }); + } + + [ConditionalFact] + public void Autoincrement_works_with_value_converter_to_int() + { + Test( + builder => + { + builder.Entity(e => + { + e.Property(p => p.Id).HasConversion().UseAutoincrement(); + }); + }, + AddBoilerPlate(""" + modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTestBase+EntityWithConverterPk", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + SqlitePropertyBuilderExtensions.UseAutoincrement(b.Property("Id")); + + b.HasKey("Id"); + + b.ToTable("EntityWithConverterPk", "DefaultSchema"); + }); + """), + model => + { + var entity = model.FindEntityType(typeof(EntityWithConverterPk)); + var property = entity!.FindProperty("Id"); + Assert.Equal(SqliteValueGenerationStrategy.Autoincrement, Microsoft.EntityFrameworkCore.SqlitePropertyExtensions.GetValueGenerationStrategy(property!)); + }); + } + + [ConditionalFact] + public void No_autoincrement_annotation_generated_for_non_autoincrement_property() + { + Test( + builder => + { + builder.Entity(e => + { + e.Property(p => p.Id).ValueGeneratedNever(); + }); + }, + AddBoilerPlate(""" + modelBuilder.Entity("Microsoft.EntityFrameworkCore.Migrations.Design.CSharpMigrationsGeneratorTestBase+EntityWithAutoincrement", b => + { + b.Property("Id") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("EntityWithAutoincrement", "DefaultSchema"); + }); + """, usingMetadata: false), + model => + { + var entity = model.FindEntityType(typeof(EntityWithAutoincrement)); + var property = entity!.FindProperty("Id"); + Assert.Equal(SqliteValueGenerationStrategy.None, Microsoft.EntityFrameworkCore.SqlitePropertyExtensions.GetValueGenerationStrategy(property!)); + }); + } + + protected override TestHelpers TestHelpers + => SqliteTestHelpers.Instance; + + protected override SqliteTestHelpers.TestModelBuilder CreateConventionalModelBuilder() + => TestHelpers.CreateConventionBuilder( + addServices: SqliteNetTopologySuiteServiceCollectionExtensions.AddEntityFrameworkSqliteNetTopologySuite); + + protected override CSharpMigrationsGenerator CreateMigrationsGenerator() + { + var sqliteTypeMappingSource = new SqliteTypeMappingSource( + TestServiceFactory.Instance.Create(), + new RelationalTypeMappingSourceDependencies( + [new SqliteNetTopologySuiteTypeMappingSourcePlugin(NtsGeometryServices.Instance)])); + + var codeHelper = new CSharpHelper(sqliteTypeMappingSource); + + var sqliteAnnotationCodeGenerator = new SqliteAnnotationCodeGenerator( + new AnnotationCodeGeneratorDependencies(sqliteTypeMappingSource)); + + var generator = new CSharpMigrationsGenerator( + new MigrationsCodeGeneratorDependencies( + sqliteTypeMappingSource, + sqliteAnnotationCodeGenerator), + new CSharpMigrationsGeneratorDependencies( + codeHelper, + new CSharpMigrationOperationGenerator( + new CSharpMigrationOperationGeneratorDependencies( + codeHelper)), + new CSharpSnapshotGenerator( + new CSharpSnapshotGeneratorDependencies( + codeHelper, sqliteTypeMappingSource, sqliteAnnotationCodeGenerator)))); + + return generator; + } + + protected override ICollection GetReferences() + => new List + { + BuildReference.ByName("Microsoft.EntityFrameworkCore"), + BuildReference.ByName("Microsoft.EntityFrameworkCore.Abstractions"), + BuildReference.ByName("Microsoft.EntityFrameworkCore.Relational"), + BuildReference.ByName("Microsoft.EntityFrameworkCore.Sqlite"), + BuildReference.ByName("Microsoft.EntityFrameworkCore.Design.Tests") + }; + + protected override IServiceCollection GetServices() + => new ServiceCollection().AddEntityFrameworkSqliteNetTopologySuite(); +} diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs index 53ee02df81c..dade6edb6ff 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.ModelSnapshot.cs @@ -117,7 +117,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) """, modelSnapshotCode, ignoreLineEndingDifferences: true); - var snapshot = CompileModelSnapshot(modelSnapshotCode, "MyNamespace.MySnapshot"); + var snapshot = CompileModelSnapshot(modelSnapshotCode, "MyNamespace.MySnapshot", typeof(MyContext)); Assert.Equal(2, snapshot.Model.GetEntityTypes().Count()); } @@ -180,7 +180,7 @@ public void Snapshot_default_values_are_round_tripped() "MySnapshot", finalizedModel); - var snapshot = CompileModelSnapshot(modelSnapshotCode, "MyNamespace.MySnapshot"); + var snapshot = CompileModelSnapshot(modelSnapshotCode, "MyNamespace.MySnapshot", typeof(MyContext)); var entityType = snapshot.Model.GetEntityTypes().Single(); Assert.Equal(typeof(EntityWithEveryPrimitive).FullName + " (Dictionary)", entityType.DisplayName()); @@ -694,10 +694,10 @@ public virtual void Model_Fluent_APIs_are_properly_generated() """), o => { - Assert.Equal(SqlServerValueGenerationStrategy.SequenceHiLo, o.GetValueGenerationStrategy()); + Assert.Equal(SqlServerValueGenerationStrategy.SequenceHiLo, Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(o.GetEntityTypes().Single().GetProperty("Id"))); Assert.Equal( SqlServerValueGenerationStrategy.SequenceHiLo, - o.GetEntityTypes().Single().GetProperty("Id").GetValueGenerationStrategy()); + Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(o.GetEntityTypes().Single().GetProperty("Id"))); }); [ConditionalFact] @@ -735,10 +735,10 @@ public virtual void Model_fluent_APIs_for_sequence_key_are_properly_generated() """), o => { - Assert.Equal(SqlServerValueGenerationStrategy.Sequence, o.GetValueGenerationStrategy()); + Assert.Equal(SqlServerValueGenerationStrategy.Sequence, Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(o.GetEntityTypes().Single().GetProperty("Id"))); Assert.Equal( SqlServerValueGenerationStrategy.Sequence, - o.GetEntityTypes().Single().GetProperty("Id").GetValueGenerationStrategy()); + Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(o.GetEntityTypes().Single().GetProperty("Id"))); }); [ConditionalFact] @@ -1569,12 +1569,12 @@ public virtual void Entity_splitting_is_stored_in_snapshot_with_tables() Assert.Equal(nameof(Order), orderEntityType.GetTableName()); var id = orderEntityType.FindProperty("Id"); - Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, id.GetValueGenerationStrategy()); + Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(id)); Assert.Equal(1, id.GetIdentitySeed()); Assert.Equal(1, id.GetIdentityIncrement()); var overrides = id.FindOverrides(StoreObjectIdentifier.Create(orderEntityType, StoreObjectType.Table).Value)!; - Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, overrides.GetValueGenerationStrategy()); + Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(overrides)); Assert.Equal(2, overrides.GetIdentitySeed()); Assert.Equal(3, overrides.GetIdentityIncrement()); Assert.Equal("arr", overrides["fii"]); @@ -2255,7 +2255,7 @@ public virtual void Model_use_identity_columns_custom_seed_increment() Assert.Equal(5, o.GetIdentityIncrement()); var property = o.FindEntityType("Building").FindProperty("Id"); - Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, property.GetValueGenerationStrategy()); + Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(property)); Assert.Equal(long.MaxValue, property.GetIdentitySeed()); Assert.Equal(5, property.GetIdentityIncrement()); }); @@ -4368,7 +4368,7 @@ public virtual void Owned_types_mapped_to_json_are_stored_in_snapshot() b3.Property("EntityWithStringKeyEntityWithTwoPropertiesEntityWithOnePropertyId"); b3.Property("__synthesizedOrdinal") - .ValueGeneratedOnAdd(); + .ValueGeneratedOnAddOrUpdate(); b3.Property("Id"); @@ -4628,10 +4628,10 @@ public virtual void Property_ValueGenerated_non_identity() { var id = model.GetEntityTypes().Single().GetProperty(nameof(EntityWithEnumType.Id)); Assert.Equal(ValueGenerated.OnAdd, id.ValueGenerated); - Assert.Equal(SqlServerValueGenerationStrategy.None, id.GetValueGenerationStrategy()); + Assert.Equal(SqlServerValueGenerationStrategy.None, Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(id)); var day = model.GetEntityTypes().Single().GetProperty(nameof(EntityWithEnumType.Day)); Assert.Equal(ValueGenerated.OnAdd, day.ValueGenerated); - Assert.Equal(SqlServerValueGenerationStrategy.None, day.GetValueGenerationStrategy()); + Assert.Equal(SqlServerValueGenerationStrategy.None, Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(day)); }); [ConditionalFact] @@ -5724,7 +5724,7 @@ public virtual void Property_with_identity_column() o => { var property = o.FindEntityType("Building").FindProperty("Id"); - Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, property.GetValueGenerationStrategy()); + Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(property)); Assert.Equal(1, property.GetIdentitySeed()); Assert.Equal(1, property.GetIdentityIncrement()); }); @@ -5763,7 +5763,7 @@ public virtual void Property_with_identity_column_custom_seed() o => { var property = o.FindEntityType("Building").FindProperty("Id"); - Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, property.GetValueGenerationStrategy()); + Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(property)); Assert.Equal(5, property.GetIdentitySeed()); Assert.Equal(1, property.GetIdentityIncrement()); }); @@ -5802,7 +5802,7 @@ public virtual void Property_with_identity_column_custom_increment() o => { var property = o.FindEntityType("Building").FindProperty("Id"); - Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, property.GetValueGenerationStrategy()); + Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(property)); Assert.Equal(1, property.GetIdentitySeed()); Assert.Equal(5, property.GetIdentityIncrement()); }); @@ -5841,7 +5841,7 @@ public virtual void Property_with_identity_column_custom_seed_increment() o => { var property = o.FindEntityType("Building").FindProperty("Id"); - Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, property.GetValueGenerationStrategy()); + Assert.Equal(SqlServerValueGenerationStrategy.IdentityColumn, Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(property)); Assert.Equal(5, property.GetIdentitySeed()); Assert.Equal(5, property.GetIdentityIncrement()); }); @@ -8570,7 +8570,7 @@ protected virtual string GetHeading(bool empty = false) """ + (empty ? null : Environment.NewLine); - protected virtual ICollection GetReferences() + protected override ICollection GetReferences() => new List { BuildReference.ByName("Microsoft.EntityFrameworkCore"), @@ -8613,93 +8613,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) """; - protected void Test(Action buildModel, string expectedCode, Action assert) - => Test(buildModel, expectedCode, (m, _) => assert(m)); + protected override IServiceCollection GetServices() + => new ServiceCollection().AddEntityFrameworkSqlServerNetTopologySuite(); - protected void Test(Action buildModel, string expectedCode, Action assert, bool validate = false) - { - var modelBuilder = CreateConventionalModelBuilder(); - modelBuilder.HasDefaultSchema("DefaultSchema"); - modelBuilder.HasChangeTrackingStrategy(ChangeTrackingStrategy.Snapshot); - modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersion); - buildModel(modelBuilder); - - var model = modelBuilder.FinalizeModel(designTime: true, skipValidation: !validate); - - Test(model, expectedCode, assert); - } - - protected void Test(IModel model, string expectedCode, Action assert) - { - var generator = CreateMigrationsGenerator(); - var code = generator.GenerateSnapshot("RootNamespace", typeof(DbContext), "Snapshot", model); - - var modelFromSnapshot = BuildModelFromSnapshotSource(code); - assert(modelFromSnapshot, model); - - try - { - Assert.Equal(expectedCode, code, ignoreLineEndingDifferences: true); - } - catch (EqualException e) - { - throw new Exception(e.Message + Environment.NewLine + Environment.NewLine + "-- Actual code:" + Environment.NewLine + code); - } - - var targetOptionsBuilder = TestHelpers - .AddProviderOptions(new DbContextOptionsBuilder()) - .UseModel(model) - .EnableSensitiveDataLogging(); - - var modelDiffer = CreateModelDiffer(targetOptionsBuilder.Options); - - var noopOperations = modelDiffer.GetDifferences(modelFromSnapshot.GetRelationalModel(), model.GetRelationalModel()); - Assert.Empty(noopOperations); - } - - protected IModel BuildModelFromSnapshotSource(string code) - { - var build = new BuildSource { Sources = { { "Snapshot.cs", code } } }; - - foreach (var buildReference in GetReferences()) - { - build.References.Add(buildReference); - } - - var assembly = build.BuildInMemory(); - var snapshotType = assembly.GetType("RootNamespace.Snapshot"); - - var buildModelMethod = snapshotType.GetMethod( - "BuildModel", - BindingFlags.Instance | BindingFlags.NonPublic, - null, - [typeof(ModelBuilder)], - null); - - var builder = new ModelBuilder(); - builder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersion); - - buildModelMethod.Invoke( - Activator.CreateInstance(snapshotType), - [builder]); - - var services = TestHelpers.CreateContextServices(new ServiceCollection().AddEntityFrameworkSqlServerNetTopologySuite()); - - var processor = new SnapshotModelProcessor(new TestOperationReporter(), services.GetService()); - return processor.Process(builder.Model); - } - - protected TestHelpers.TestModelBuilder CreateConventionalModelBuilder() + protected override TestHelpers.TestModelBuilder CreateConventionalModelBuilder() => TestHelpers.CreateConventionBuilder( addServices: SqlServerNetTopologySuiteServiceCollectionExtensions.AddEntityFrameworkSqlServerNetTopologySuite); - protected virtual MigrationsModelDiffer CreateModelDiffer(DbContextOptions options) - => (MigrationsModelDiffer)TestHelpers.CreateContext(options).GetService(); - - protected TestHelpers TestHelpers + protected override TestHelpers TestHelpers => SqlServerTestHelpers.Instance; - protected CSharpMigrationsGenerator CreateMigrationsGenerator() + protected override CSharpMigrationsGenerator CreateMigrationsGenerator() { var sqlServerTypeMappingSource = new SqlServerTypeMappingSource( TestServiceFactory.Instance.Create(), diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs index 5a35ccd2067..2625501a591 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTest.cs @@ -15,7 +15,7 @@ // ReSharper disable UnusedMember.Local namespace Microsoft.EntityFrameworkCore.Migrations.Design; -public partial class CSharpMigrationsGeneratorTest +public partial class CSharpMigrationsGeneratorTest : CSharpMigrationsGeneratorTestBase { private static readonly string _nl = Environment.NewLine; private static readonly string _toTable = _nl + @"entityTypeBuilder.ToTable(""WithAnnotations"")"; @@ -515,7 +515,7 @@ public void Snapshot_with_enum_discriminator_uses_converted_values() "MySnapshot", finalizedModel); - var snapshotModel = CompileModelSnapshot(modelSnapshotCode, "MyNamespace.MySnapshot").Model; + var snapshotModel = CompileModelSnapshot(modelSnapshotCode, "MyNamespace.MySnapshot", typeof(MyContext)).Model; Assert.Equal((int)RawEnum.A, snapshotModel.FindEntityType(typeof(WithAnnotations)).GetDiscriminatorValue()); Assert.Equal((int)RawEnum.B, snapshotModel.FindEntityType(typeof(Derived)).GetDiscriminatorValue()); @@ -745,26 +745,6 @@ private class EntityWithConstructorBinding(int id) public int Id { get; } = id; } - private ModelSnapshot CompileModelSnapshot(string code, string modelSnapshotTypeName) - { - var build = new BuildSource { Sources = { { "Snapshot.cs", code } } }; - - foreach (var buildReference in GetReferences()) - { - build.References.Add(buildReference); - } - - var assembly = build.BuildInMemory(); - - var snapshotType = assembly.GetType(modelSnapshotTypeName, throwOnError: true, ignoreCase: false); - - var contextTypeAttribute = snapshotType.GetCustomAttribute(); - Assert.NotNull(contextTypeAttribute); - Assert.Equal(typeof(MyContext), contextTypeAttribute.ContextType); - - return (ModelSnapshot)Activator.CreateInstance(snapshotType); - } - public class MyContext; [ConditionalFact] diff --git a/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTestBase.cs b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTestBase.cs new file mode 100644 index 00000000000..ebe7a7a9c63 --- /dev/null +++ b/test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationsGeneratorTestBase.cs @@ -0,0 +1,129 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Migrations.Internal; +using Xunit.Sdk; + +namespace Microsoft.EntityFrameworkCore.Migrations.Design; + +public abstract class CSharpMigrationsGeneratorTestBase +{ + protected abstract ICollection GetReferences(); + + protected abstract TestHelpers TestHelpers { get; } + + protected void Test(Action buildModel, string expectedCode, Action assert) + => Test(buildModel, expectedCode, (m, _) => assert(m)); + + protected void Test(Action buildModel, string expectedCode, Action assert, bool validate = false) + { + var modelBuilder = CreateConventionalModelBuilder(); + modelBuilder.HasDefaultSchema("DefaultSchema"); + modelBuilder.HasChangeTrackingStrategy(ChangeTrackingStrategy.Snapshot); + modelBuilder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersion); + buildModel(modelBuilder); + + var model = modelBuilder.FinalizeModel(designTime: true, skipValidation: !validate); + + Test(model, expectedCode, assert); + } + + protected void Test(IModel model, string expectedCode, Action assert) + { + var generator = CreateMigrationsGenerator(); + var code = generator.GenerateSnapshot("RootNamespace", typeof(DbContext), "Snapshot", model); + + var modelFromSnapshot = BuildModelFromSnapshotSource(code); + assert(modelFromSnapshot, model); + + try + { + Assert.Equal(expectedCode, code, ignoreLineEndingDifferences: true); + } + catch (EqualException e) + { + throw new Exception(e.Message + Environment.NewLine + Environment.NewLine + "-- Actual code:" + Environment.NewLine + code); + } + + var targetOptionsBuilder = TestHelpers + .AddProviderOptions(new DbContextOptionsBuilder()) + .UseModel(model) + .EnableSensitiveDataLogging(); + + var modelDiffer = CreateModelDiffer(targetOptionsBuilder.Options); + + var noopOperations = modelDiffer.GetDifferences(modelFromSnapshot.GetRelationalModel(), model.GetRelationalModel()); + Assert.Empty(noopOperations); + } + + protected abstract TestHelpers.TestModelBuilder CreateConventionalModelBuilder(); + + protected abstract CSharpMigrationsGenerator CreateMigrationsGenerator(); + + protected virtual IModel BuildModelFromSnapshotSource(string code) + { + var build = new BuildSource { Sources = { { "Snapshot.cs", code } } }; + + foreach (var buildReference in GetReferences()) + { + build.References.Add(buildReference); + } + + var assembly = build.BuildInMemory(); + var snapshotType = assembly.GetType("RootNamespace.Snapshot"); + + var buildModelMethod = snapshotType.GetMethod( + "BuildModel", + BindingFlags.Instance | BindingFlags.NonPublic, + null, + [typeof(ModelBuilder)], + null); + + var builder = new ModelBuilder(); + builder.Model.RemoveAnnotation(CoreAnnotationNames.ProductVersion); + + buildModelMethod.Invoke( + Activator.CreateInstance(snapshotType), + [builder]); + + var services = TestHelpers.CreateContextServices(GetServices()); + var processor = new SnapshotModelProcessor(new TestOperationReporter(), services.GetService()); + return processor.Process(builder.Model); + } + protected virtual MigrationsModelDiffer CreateModelDiffer(DbContextOptions options) + => (MigrationsModelDiffer)TestHelpers.CreateContext(options).GetService(); + + protected virtual IServiceCollection GetServices() + => new ServiceCollection(); + + protected virtual ModelSnapshot CompileModelSnapshot(string code, string modelSnapshotTypeName, Type contextType) + { + var build = new BuildSource { Sources = { { "Snapshot.cs", code } } }; + + foreach (var buildReference in GetReferences()) + { + build.References.Add(buildReference); + } + + var assembly = build.BuildInMemory(); + + var snapshotType = assembly.GetType(modelSnapshotTypeName, throwOnError: true, ignoreCase: false); + + var contextTypeAttribute = snapshotType.GetCustomAttribute(); + Assert.NotNull(contextTypeAttribute); + Assert.Equal(contextType, contextTypeAttribute.ContextType); + + return (ModelSnapshot)Activator.CreateInstance(snapshotType); + } + + protected class EntityWithAutoincrement + { + public int Id { get; set; } + } + + protected class EntityWithConverterPk + { + public long Id { get; set; } + } +} diff --git a/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs b/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs index afd2e2cbaa5..0b213ad4f20 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/SnapshotModelProcessorTest.cs @@ -262,15 +262,15 @@ private static IModel PreprocessModel(ModelSnapshot snapshot) property.SetValueGenerated(null, ConfigurationSource.Explicit); } - if (property.GetValueGenerationStrategy() != SqlServerValueGenerationStrategy.None) + if (Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(property) != SqlServerValueGenerationStrategy.None) { - property.SetValueGenerationStrategy(null); + Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.SetValueGenerationStrategy(property, null); } } - else if (property.GetValueGenerationStrategy() is var strategy + else if (Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(property) is var strategy && strategy != SqlServerValueGenerationStrategy.None) { - property.SetValueGenerationStrategy(strategy); + Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.SetValueGenerationStrategy(property, strategy); } } } diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpDbContextGeneratorTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpDbContextGeneratorTest.cs index 8d2afa05a25..0d3392faeee 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpDbContextGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpDbContextGeneratorTest.cs @@ -1330,7 +1330,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) { var entityType = Assert.Single(model.GetEntityTypes()); var property = Assert.Single(entityType.GetProperties()); - Assert.Equal(SqlServerValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + Assert.Equal(SqlServerValueGenerationStrategy.None, Microsoft.EntityFrameworkCore.SqlServerPropertyExtensions.GetValueGenerationStrategy(property)); }); [ConditionalTheory, InlineData(false), InlineData(true)] diff --git a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs index faeff64d79e..155f91509c6 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/OwnedType0EntityType.cs @@ -104,7 +104,8 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas var __synthesizedOrdinal = runtimeEntityType.AddProperty( "__synthesizedOrdinal", typeof(int), - valueGenerated: ValueGenerated.OnAdd, + valueGenerated: ValueGenerated.OnAddOrUpdate, + beforeSaveBehavior: PropertySaveBehavior.Ignore, afterSaveBehavior: PropertySaveBehavior.Throw, sentinel: 0); __synthesizedOrdinal.SetAccessors( @@ -132,7 +133,7 @@ public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType bas int (int v) => v, int (int v) => v)); __synthesizedOrdinal.SetCurrentValueComparer(new EntryCurrentValueComparer(__synthesizedOrdinal)); - __synthesizedOrdinal.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + __synthesizedOrdinal.AddAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.None); var details = runtimeEntityType.AddProperty( "Details", diff --git a/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsSqliteTest.cs index 43cc3985995..b8c91b18d60 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Migrations/MigrationsSqliteTest.cs @@ -2348,6 +2348,177 @@ await Test( """); } + [ConditionalFact] + public virtual async Task Create_table_with_autoincrement_and_value_converter() + { + await Test( + builder => { }, + builder => builder.Entity( + x => + { + x.Property(e => e.Id).HasConversion( + v => v.Value, + v => new ProductId(v)).UseAutoincrement(); + x.HasKey(e => e.Id); + x.Property(e => e.Name); + }), + model => + { + var table = Assert.Single(model.Tables); + Assert.Equal("ProductWithStrongId", table.Name); + Assert.Equal(2, table.Columns.Count()); + + var idColumn = Assert.Single(table.Columns, c => c.Name == "Id"); + Assert.False(idColumn.IsNullable); + }); + + AssertSql( + """ +CREATE TABLE "ProductWithStrongId" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_ProductWithStrongId" PRIMARY KEY AUTOINCREMENT, + "Name" TEXT NULL +); +"""); + } + + [ConditionalFact] + public virtual async Task Create_table_with_autoincrement_and_value_converter_by_convention() + { + await Test( + builder => { }, + builder => builder.Entity( + x => + { + x.Property(e => e.Id).HasConversion( + v => v.Value, + v => new ProductId(v)); + x.HasKey(e => e.Id); + x.Property(e => e.Name); + }), + model => + { + var table = Assert.Single(model.Tables); + Assert.Equal("ProductWithStrongId", table.Name); + Assert.Equal(2, table.Columns.Count()); + + var idColumn = Assert.Single(table.Columns, c => c.Name == "Id"); + Assert.False(idColumn.IsNullable); + }); + + AssertSql( + """ +CREATE TABLE "ProductWithStrongId" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_ProductWithStrongId" PRIMARY KEY, + "Name" TEXT NULL +); +"""); + } + + [ConditionalFact] + public virtual async Task Create_table_with_composite_primary_key_ignores_autoincrement() + { + await Test( + builder => { }, + builder => builder.Entity( + "CompositeEntity", + x => + { + x.Property("Id1").UseAutoincrement(); + x.Property("Id2"); + x.HasKey("Id1", "Id2"); + }), + model => + { + var table = Assert.Single(model.Tables); + Assert.Equal("CompositeEntity", table.Name); + Assert.Equal(2, table.Columns.Count()); + + var id1Column = Assert.Single(table.Columns, c => c.Name == "Id1"); + Assert.False(id1Column.IsNullable); + var id2Column = Assert.Single(table.Columns, c => c.Name == "Id2"); + Assert.False(id2Column.IsNullable); + }); + + AssertSql( + """ +CREATE TABLE "CompositeEntity" ( + "Id1" INTEGER NOT NULL, + "Id2" INTEGER NOT NULL, + CONSTRAINT "PK_CompositeEntity" PRIMARY KEY ("Id1", "Id2") +); +"""); + } + + [ConditionalFact] + public virtual async Task Alter_column_remove_autoincrement() + { + await Test( + builder => builder.Entity( + "Product", + x => + { + x.Property("Id").UseAutoincrement(); + x.HasKey("Id"); + x.Property("Name"); + }), + builder => builder.Entity( + "Product", + x => + { + x.Property("Id").ValueGeneratedNever(); + x.HasKey("Id"); + x.Property("Name"); + }), + model => + { + var table = Assert.Single(model.Tables); + Assert.Equal("Product", table.Name); + Assert.Equal(2, table.Columns.Count()); + + var idColumn = Assert.Single(table.Columns, c => c.Name == "Id"); + Assert.False(idColumn.IsNullable); + }); + + AssertSql( + """ +CREATE TABLE "ef_temp_Product" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Product" PRIMARY KEY, + "Name" TEXT NULL +); +""", + // + """ +INSERT INTO "ef_temp_Product" ("Id", "Name") +SELECT "Id", "Name" +FROM "Product"; +""", + // + """ +PRAGMA foreign_keys = 0; +""", + // + """ +DROP TABLE "Product"; +""", + // + """ +ALTER TABLE "ef_temp_Product" RENAME TO "Product"; +""", + // + """ +PRAGMA foreign_keys = 1; +"""); + } + + // Test entities for autoincrement tests + public record struct ProductId(int Value); + + public class ProductWithStrongId + { + public ProductId Id { get; set; } + public string? Name { get; set; } + } + protected virtual async Task AssertNotSupportedAsync(Func action, string? message = null) { var ex = await Assert.ThrowsAsync(action); diff --git a/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteModelBuilderTestBase.cs b/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteModelBuilderTestBase.cs index b2cf17879a8..86503a4e80f 100644 --- a/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteModelBuilderTestBase.cs +++ b/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteModelBuilderTestBase.cs @@ -8,7 +8,197 @@ namespace Microsoft.EntityFrameworkCore.ModelBuilding; public class SqliteModelBuilderTestBase : RelationalModelBuilderTest { public abstract class SqliteNonRelationship(SqliteModelBuilderFixture fixture) - : RelationalNonRelationshipTestBase(fixture), IClassFixture; + : RelationalNonRelationshipTestBase(fixture), IClassFixture + { + [ConditionalFact] + public void UseAutoincrement_sets_value_generation_strategy() + { + var modelBuilder = CreateModelBuilder(); + + var propertyBuilder = modelBuilder + .Entity() + .Property(e => e.Id); + + propertyBuilder.UseAutoincrement(); + + Assert.Equal(SqliteValueGenerationStrategy.Autoincrement, propertyBuilder.Metadata.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void Generic_UseAutoincrement_sets_value_generation_strategy() + { + var modelBuilder = CreateModelBuilder(); + + var propertyBuilder = modelBuilder + .Entity() + .Property(e => e.Id); + + propertyBuilder.UseAutoincrement(); + + Assert.Equal(SqliteValueGenerationStrategy.Autoincrement, propertyBuilder.Metadata.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void Default_value_generation_strategy_for_integer_primary_key() + { + var modelBuilder = CreateModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.Id) + .Metadata; + + var model = modelBuilder.FinalizeModel(); + + // With conventions, integer primary keys should get autoincrement + Assert.Equal(SqliteValueGenerationStrategy.Autoincrement, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_for_non_primary_key() + { + var modelBuilder = CreateModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.OtherId) + .Metadata; + + var model = modelBuilder.FinalizeModel(); + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_for_non_integer_primary_key() + { + var modelBuilder = CreateModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.Id) + .Metadata; + + var model = modelBuilder.FinalizeModel(); + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_for_composite_primary_key() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder + .Entity(b => + { + b.HasKey(e => new { e.Id1, e.Id2 }); + }); + + var property1 = modelBuilder.Entity().Property(e => e.Id1).Metadata; + var property2 = modelBuilder.Entity().Property(e => e.Id2).Metadata; + + var model = modelBuilder.FinalizeModel(); + + Assert.Equal(SqliteValueGenerationStrategy.None, property1.GetValueGenerationStrategy()); + Assert.Equal(SqliteValueGenerationStrategy.None, property2.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_when_default_value_set() + { + var modelBuilder = CreateModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.Id) + .HasDefaultValue(42) + .Metadata; + + var model = modelBuilder.FinalizeModel(); + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_when_default_value_sql_set() + { + var modelBuilder = CreateModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.Id) + .HasDefaultValueSql("1") + .Metadata; + + var model = modelBuilder.FinalizeModel(); + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_when_computed_column_sql_set() + { + var modelBuilder = CreateModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.Id) + .HasComputedColumnSql("1") + .Metadata; + + var model = modelBuilder.FinalizeModel(); + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_when_property_is_foreign_key() + { + var modelBuilder = CreateModelBuilder(); + + modelBuilder.Entity(b => + { + b.HasKey(e => e.Id); + b.Property(e => e.CustomerId); + b.HasOne() + .WithMany() + .HasForeignKey(e => e.CustomerId); + }); + + var property = modelBuilder.Entity().Property(e => e.CustomerId).Metadata; + + var model = modelBuilder.FinalizeModel(); + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + private class Customer + { + public int Id { get; set; } + public int OtherId { get; set; } + public string? Name { get; set; } + } + + private class CustomerWithStringKey + { + public string Id { get; set; } = null!; + public string? Name { get; set; } + } + + private class CustomerWithCompositeKey + { + public int Id1 { get; set; } + public int Id2 { get; set; } + public string? Name { get; set; } + } + + private class Order + { + public int Id { get; set; } + public int CustomerId { get; set; } + } + } public abstract class SqliteComplexType(SqliteModelBuilderFixture fixture) : RelationalComplexTypeTestBase(fixture), IClassFixture; diff --git a/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteTestModelBuilderExtensions.cs b/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteTestModelBuilderExtensions.cs index 28b6cac6b7f..f6576e42b37 100644 --- a/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteTestModelBuilderExtensions.cs +++ b/test/EFCore.Sqlite.FunctionalTests/ModelBuilding/SqliteTestModelBuilderExtensions.cs @@ -1,4 +1,23 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +namespace Microsoft.EntityFrameworkCore.ModelBuilding; +public static class SqliteTestModelBuilderExtensions +{ + public static ModelBuilderTest.TestPropertyBuilder UseAutoincrement( + this ModelBuilderTest.TestPropertyBuilder builder) + { + switch (builder) + { + case IInfrastructure> genericBuilder: + genericBuilder.Instance.UseAutoincrement(); + break; + case IInfrastructure nonGenericBuilder: + nonGenericBuilder.Instance.UseAutoincrement(); + break; + } + + return builder; + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/AutoIncrementEntityEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/AutoIncrementEntityEntityType.cs new file mode 100644 index 00000000000..93394873614 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/AutoIncrementEntityEntityType.cs @@ -0,0 +1,171 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal; +using Microsoft.EntityFrameworkCore.Storage; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class AutoIncrementEntityEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelSqliteTest+AutoIncrementEntity", + typeof(CompiledModelSqliteTest.AutoIncrementEntity), + baseEntityType, + propertyCount: 2, + keyCount: 1); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(int), + propertyInfo: typeof(CompiledModelSqliteTest.AutoIncrementEntity).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelSqliteTest.AutoIncrementEntity).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0); + id.SetGetter( + int (CompiledModelSqliteTest.AutoIncrementEntity instance) => AutoIncrementEntityUnsafeAccessors.Id(instance), + bool (CompiledModelSqliteTest.AutoIncrementEntity instance) => AutoIncrementEntityUnsafeAccessors.Id(instance) == 0); + id.SetSetter( + CompiledModelSqliteTest.AutoIncrementEntity (CompiledModelSqliteTest.AutoIncrementEntity instance, int value) => + { + AutoIncrementEntityUnsafeAccessors.Id(instance) = value; + return instance; + }); + id.SetMaterializationSetter( + CompiledModelSqliteTest.AutoIncrementEntity (CompiledModelSqliteTest.AutoIncrementEntity instance, int value) => + { + AutoIncrementEntityUnsafeAccessors.Id(instance) = value; + return instance; + }); + id.SetAccessors( + int (IInternalEntry entry) => (entry.FlaggedAsStoreGenerated(0) ? entry.ReadStoreGeneratedValue(0) : (entry.FlaggedAsTemporary(0) && AutoIncrementEntityUnsafeAccessors.Id(((CompiledModelSqliteTest.AutoIncrementEntity)(entry.Entity))) == 0 ? entry.ReadTemporaryValue(0) : AutoIncrementEntityUnsafeAccessors.Id(((CompiledModelSqliteTest.AutoIncrementEntity)(entry.Entity))))), + int (IInternalEntry entry) => AutoIncrementEntityUnsafeAccessors.Id(((CompiledModelSqliteTest.AutoIncrementEntity)(entry.Entity))), + int (IInternalEntry entry) => entry.ReadOriginalValue(id, 0), + int (IInternalEntry entry) => ((InternalEntityEntry)(entry)).ReadRelationshipSnapshotValue(id, 0)); + id.SetPropertyIndexes( + index: 0, + originalValueIndex: 0, + shadowIndex: -1, + relationshipIndex: 0, + storeGenerationIndex: 0); + id.TypeMapping = IntTypeMapping.Default.Clone( + comparer: new ValueComparer( + bool (int v1, int v2) => v1 == v2, + int (int v) => v, + int (int v) => v), + keyComparer: new ValueComparer( + bool (int v1, int v2) => v1 == v2, + int (int v) => v, + int (int v) => v), + providerValueComparer: new ValueComparer( + bool (int v1, int v2) => v1 == v2, + int (int v) => v, + int (int v) => v), + mappingInfo: new RelationalTypeMappingInfo( + storeTypeName: "INTEGER")); + id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + + var name = runtimeEntityType.AddProperty( + "Name", + typeof(string), + propertyInfo: typeof(CompiledModelSqliteTest.AutoIncrementEntity).GetProperty("Name", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelSqliteTest.AutoIncrementEntity).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + name.SetGetter( + string (CompiledModelSqliteTest.AutoIncrementEntity instance) => AutoIncrementEntityUnsafeAccessors.Name(instance), + bool (CompiledModelSqliteTest.AutoIncrementEntity instance) => AutoIncrementEntityUnsafeAccessors.Name(instance) == null); + name.SetSetter( + CompiledModelSqliteTest.AutoIncrementEntity (CompiledModelSqliteTest.AutoIncrementEntity instance, string value) => + { + AutoIncrementEntityUnsafeAccessors.Name(instance) = value; + return instance; + }); + name.SetMaterializationSetter( + CompiledModelSqliteTest.AutoIncrementEntity (CompiledModelSqliteTest.AutoIncrementEntity instance, string value) => + { + AutoIncrementEntityUnsafeAccessors.Name(instance) = value; + return instance; + }); + name.SetAccessors( + string (IInternalEntry entry) => AutoIncrementEntityUnsafeAccessors.Name(((CompiledModelSqliteTest.AutoIncrementEntity)(entry.Entity))), + string (IInternalEntry entry) => AutoIncrementEntityUnsafeAccessors.Name(((CompiledModelSqliteTest.AutoIncrementEntity)(entry.Entity))), + string (IInternalEntry entry) => entry.ReadOriginalValue(name, 1), + string (IInternalEntry entry) => entry.GetCurrentValue(name)); + name.SetPropertyIndexes( + index: 1, + originalValueIndex: 1, + shadowIndex: -1, + relationshipIndex: -1, + storeGenerationIndex: -1); + name.TypeMapping = SqliteStringTypeMapping.Default; + + var key = runtimeEntityType.AddKey( + new[] { id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + var id = runtimeEntityType.FindProperty("Id"); + var name = runtimeEntityType.FindProperty("Name"); + var key = runtimeEntityType.FindKey(new[] { id }); + key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); + key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); + runtimeEntityType.SetOriginalValuesFactory( + ISnapshot (IInternalEntry source) => + { + var structuralType = ((CompiledModelSqliteTest.AutoIncrementEntity)(source.Entity)); + return ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)id).GetValueComparer())).Snapshot(source.GetCurrentValue(id)), (source.GetCurrentValue(name) == null ? null : ((ValueComparer)(((IProperty)name).GetValueComparer())).Snapshot(source.GetCurrentValue(name)))))); + }); + runtimeEntityType.SetStoreGeneratedValuesFactory( + ISnapshot () => ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)id).GetValueComparer())).Snapshot(default(int)))))); + runtimeEntityType.SetTemporaryValuesFactory( + ISnapshot (IInternalEntry source) => ((ISnapshot)(new Snapshot(default(int))))); + runtimeEntityType.SetShadowValuesFactory( + ISnapshot (IDictionary source) => Snapshot.Empty); + runtimeEntityType.SetEmptyShadowValuesFactory( + ISnapshot () => Snapshot.Empty); + runtimeEntityType.SetRelationshipSnapshotFactory( + ISnapshot (IInternalEntry source) => + { + var structuralType = ((CompiledModelSqliteTest.AutoIncrementEntity)(source.Entity)); + return ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))))); + }); + runtimeEntityType.SetCounts(new PropertyCounts( + propertyCount: 2, + navigationCount: 0, + complexPropertyCount: 0, + complexCollectionCount: 0, + originalValueCount: 2, + shadowCount: 0, + relationshipCount: 1, + storeGeneratedCount: 1)); + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "AutoIncrementEntity"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/AutoIncrementEntityUnsafeAccessors.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/AutoIncrementEntityUnsafeAccessors.cs new file mode 100644 index 00000000000..536893c1d93 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/AutoIncrementEntityUnsafeAccessors.cs @@ -0,0 +1,19 @@ +// +using System; +using System.Runtime.CompilerServices; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + public static class AutoIncrementEntityUnsafeAccessors + { + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "k__BackingField")] + public static extern ref int Id(CompiledModelSqliteTest.AutoIncrementEntity @this); + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "k__BackingField")] + public static extern ref string Name(CompiledModelSqliteTest.AutoIncrementEntity @this); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextModelBuilder.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextModelBuilder.cs index fcd8b25bd0d..c5aa429a44c 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextModelBuilder.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel/DbContextModelBuilder.cs @@ -17,12 +17,13 @@ namespace TestNamespace public partial class DbContextModel { private DbContextModel() - : base(skipDetectChanges: false, modelId: new Guid("00000000-0000-0000-0000-000000000000"), entityTypeCount: 9) + : base(skipDetectChanges: false, modelId: new Guid("00000000-0000-0000-0000-000000000000"), entityTypeCount: 10) { } partial void Initialize() { + var autoIncrementEntity = AutoIncrementEntityEntityType.Create(this); var data = DataEntityType.Create(this); var dependentBase = DependentBaseEntityType.Create(this); var manyTypes = ManyTypesEntityType.Create(this); @@ -45,6 +46,7 @@ partial void Initialize() PrincipalBaseEntityType.CreateSkipNavigation1(principalBase, principalDerived, principalBasePrincipalDerivedDependentBasebyte); PrincipalDerivedEntityType.CreateSkipNavigation1(principalDerived, principalBase, principalBasePrincipalDerivedDependentBasebyte); + AutoIncrementEntityEntityType.CreateAnnotations(autoIncrementEntity); DataEntityType.CreateAnnotations(data); DependentBaseEntityType.CreateAnnotations(dependentBase); ManyTypesEntityType.CreateAnnotations(manyTypes); @@ -62,18 +64,65 @@ private IRelationalModel CreateRelationalModel() { var relationalModel = new RelationalModel(this); - var data = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+Data")!; + var autoIncrementEntity = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelSqliteTest+AutoIncrementEntity")!; var defaultTableMappings = new List>(); - data.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings); + autoIncrementEntity.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings); + var microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase = new TableBase("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelSqliteTest+AutoIncrementEntity", null, relationalModel); + var idColumnBase = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase); + microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase.Columns.Add("Id", idColumnBase); + var nameColumnBase = new ColumnBase("Name", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase) + { + IsNullable = true + }; + microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase.Columns.Add("Name", nameColumnBase); + relationalModel.DefaultTables.Add("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelSqliteTest+AutoIncrementEntity", microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase); + var microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityMappingBase = new TableMappingBase(autoIncrementEntity, microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase, null); + microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityMappingBase, false); + defaultTableMappings.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase, autoIncrementEntity.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)nameColumnBase, autoIncrementEntity.FindProperty("Name")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityMappingBase); + + var tableMappings = new List(); + autoIncrementEntity.SetRuntimeAnnotation("Relational:TableMappings", tableMappings); + var autoIncrementEntityTable = new Table("AutoIncrementEntity", null, relationalModel); + var idColumn = new Column("Id", "INTEGER", autoIncrementEntityTable); + autoIncrementEntityTable.Columns.Add("Id", idColumn); + idColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn); + var nameColumn = new Column("Name", "TEXT", autoIncrementEntityTable) + { + IsNullable = true + }; + autoIncrementEntityTable.Columns.Add("Name", nameColumn); + nameColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(nameColumn); + relationalModel.Tables.Add(("AutoIncrementEntity", null), autoIncrementEntityTable); + var autoIncrementEntityTableMapping = new TableMapping(autoIncrementEntity, autoIncrementEntityTable, null); + autoIncrementEntityTable.AddTypeMapping(autoIncrementEntityTableMapping, false); + tableMappings.Add(autoIncrementEntityTableMapping); + RelationalModel.CreateColumnMapping(idColumn, autoIncrementEntity.FindProperty("Id")!, autoIncrementEntityTableMapping); + RelationalModel.CreateColumnMapping(nameColumn, autoIncrementEntity.FindProperty("Name")!, autoIncrementEntityTableMapping); + var pK_AutoIncrementEntity = new UniqueConstraint("PK_AutoIncrementEntity", autoIncrementEntityTable, new[] { idColumn }); + autoIncrementEntityTable.PrimaryKey = pK_AutoIncrementEntity; + pK_AutoIncrementEntity.SetRowKeyValueFactory(new SimpleRowKeyValueFactory(pK_AutoIncrementEntity)); + var pK_AutoIncrementEntityKey = RelationalModel.GetKey(this, + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelSqliteTest+AutoIncrementEntity", + new[] { "Id" }); + pK_AutoIncrementEntity.MappedKeys.Add(pK_AutoIncrementEntityKey); + RelationalModel.GetOrCreateUniqueConstraints(pK_AutoIncrementEntityKey).Add(pK_AutoIncrementEntity); + autoIncrementEntityTable.UniqueConstraints.Add("PK_AutoIncrementEntity", pK_AutoIncrementEntity); + + var data = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+Data")!; + + var defaultTableMappings0 = new List>(); + data.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings0); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase = new TableBase("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+Data", null, relationalModel); var blobColumnBase = new ColumnBase("Blob", "BLOB", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase) { IsNullable = true }; microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase.Columns.Add("Blob", blobColumnBase); - var idColumnBase = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase); - microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase.Columns.Add("Id", idColumnBase); + var idColumnBase0 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase); + microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase.Columns.Add("Id", idColumnBase0); var pointColumnBase = new ColumnBase("Point", "POINT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase) { IsNullable = true @@ -82,17 +131,17 @@ private IRelationalModel CreateRelationalModel() relationalModel.DefaultTables.Add("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+Data", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase = new TableMappingBase(data, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase, false); - defaultTableMappings.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase, data.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase); + defaultTableMappings0.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase0, data.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)blobColumnBase, data.FindProperty("Blob")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)pointColumnBase, data.FindProperty("Point")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase); - var tableMappings = new List(); - data.SetRuntimeAnnotation("Relational:TableMappings", tableMappings); + var tableMappings0 = new List(); + data.SetRuntimeAnnotation("Relational:TableMappings", tableMappings0); var dataTable = new Table("Data", null, relationalModel); - var idColumn = new Column("Id", "INTEGER", dataTable); - dataTable.Columns.Add("Id", idColumn); - idColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn); + var idColumn0 = new Column("Id", "INTEGER", dataTable); + dataTable.Columns.Add("Id", idColumn0); + idColumn0.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn0); var blobColumn = new Column("Blob", "BLOB", dataTable) { IsNullable = true @@ -108,11 +157,11 @@ private IRelationalModel CreateRelationalModel() relationalModel.Tables.Add(("Data", null), dataTable); var dataTableMapping = new TableMapping(data, dataTable, null); dataTable.AddTypeMapping(dataTableMapping, false); - tableMappings.Add(dataTableMapping); - RelationalModel.CreateColumnMapping(idColumn, data.FindProperty("Id")!, dataTableMapping); + tableMappings0.Add(dataTableMapping); + RelationalModel.CreateColumnMapping(idColumn0, data.FindProperty("Id")!, dataTableMapping); RelationalModel.CreateColumnMapping(blobColumn, data.FindProperty("Blob")!, dataTableMapping); RelationalModel.CreateColumnMapping(pointColumn, data.FindProperty("Point")!, dataTableMapping); - var pK_Data = new UniqueConstraint("PK_Data", dataTable, new[] { idColumn }); + var pK_Data = new UniqueConstraint("PK_Data", dataTable, new[] { idColumn0 }); dataTable.PrimaryKey = pK_Data; pK_Data.SetRowKeyValueFactory(new SimpleRowKeyValueFactory(pK_Data)); var pK_DataKey = RelationalModel.GetKey(this, @@ -124,8 +173,8 @@ private IRelationalModel CreateRelationalModel() var dependentBase = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentBase")!; - var defaultTableMappings0 = new List>(); - dependentBase.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings0); + var defaultTableMappings1 = new List>(); + dependentBase.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings1); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase = new TableBase("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentBase", null, relationalModel); var dataColumnBase = new ColumnBase("Data", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase) { @@ -134,11 +183,11 @@ private IRelationalModel CreateRelationalModel() microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.Columns.Add("Data", dataColumnBase); var enumDiscriminatorColumnBase = new ColumnBase("EnumDiscriminator", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.Columns.Add("EnumDiscriminator", enumDiscriminatorColumnBase); - var idColumnBase0 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase) + var idColumnBase1 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase) { IsNullable = true }; - microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.Columns.Add("Id", idColumnBase0); + microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.Columns.Add("Id", idColumnBase1); var moneyColumnBase = new ColumnBase("Money", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase) { IsNullable = true @@ -151,14 +200,14 @@ private IRelationalModel CreateRelationalModel() relationalModel.DefaultTables.Add("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentBase", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase = new TableMappingBase(dependentBase, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase, true); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase, false); - defaultTableMappings0.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); + defaultTableMappings1.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)principalAlternateIdColumnBase, dependentBase.FindProperty("PrincipalAlternateId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)principalIdColumnBase, dependentBase.FindProperty("PrincipalId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)enumDiscriminatorColumnBase, dependentBase.FindProperty("EnumDiscriminator")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase0, dependentBase.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase1, dependentBase.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); - var tableMappings0 = new List(); - dependentBase.SetRuntimeAnnotation("Relational:TableMappings", tableMappings0); + var tableMappings1 = new List(); + dependentBase.SetRuntimeAnnotation("Relational:TableMappings", tableMappings1); var dependentBasebyteTable = new Table("DependentBase", null, relationalModel); var principalIdColumn = new Column("PrincipalId", "INTEGER", dependentBasebyteTable); dependentBasebyteTable.Columns.Add("PrincipalId", principalIdColumn); @@ -175,12 +224,12 @@ private IRelationalModel CreateRelationalModel() var enumDiscriminatorColumn = new Column("EnumDiscriminator", "INTEGER", dependentBasebyteTable); dependentBasebyteTable.Columns.Add("EnumDiscriminator", enumDiscriminatorColumn); enumDiscriminatorColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(enumDiscriminatorColumn); - var idColumn0 = new Column("Id", "INTEGER", dependentBasebyteTable) + var idColumn1 = new Column("Id", "INTEGER", dependentBasebyteTable) { IsNullable = true }; - dependentBasebyteTable.Columns.Add("Id", idColumn0); - idColumn0.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn0); + dependentBasebyteTable.Columns.Add("Id", idColumn1); + idColumn1.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn1); var moneyColumn = new Column("Money", "TEXT", dependentBasebyteTable) { IsNullable = true @@ -193,39 +242,39 @@ private IRelationalModel CreateRelationalModel() IsSharedTablePrincipal = true, }; dependentBasebyteTable.AddTypeMapping(dependentBasebyteTableMapping, false); - tableMappings0.Add(dependentBasebyteTableMapping); + tableMappings1.Add(dependentBasebyteTableMapping); RelationalModel.CreateColumnMapping(principalAlternateIdColumn, dependentBase.FindProperty("PrincipalAlternateId")!, dependentBasebyteTableMapping); RelationalModel.CreateColumnMapping(principalIdColumn, dependentBase.FindProperty("PrincipalId")!, dependentBasebyteTableMapping); RelationalModel.CreateColumnMapping(enumDiscriminatorColumn, dependentBase.FindProperty("EnumDiscriminator")!, dependentBasebyteTableMapping); - RelationalModel.CreateColumnMapping(idColumn0, dependentBase.FindProperty("Id")!, dependentBasebyteTableMapping); + RelationalModel.CreateColumnMapping(idColumn1, dependentBase.FindProperty("Id")!, dependentBasebyteTableMapping); var dependentDerived = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentDerived")!; - var defaultTableMappings1 = new List>(); - dependentDerived.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings1); + var defaultTableMappings2 = new List>(); + dependentDerived.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings2); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0 = new TableMappingBase(dependentDerived, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0, false); - defaultTableMappings1.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); + defaultTableMappings2.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)principalAlternateIdColumnBase, dependentDerived.FindProperty("PrincipalAlternateId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)principalIdColumnBase, dependentDerived.FindProperty("PrincipalId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)dataColumnBase, dependentDerived.FindProperty("Data")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)enumDiscriminatorColumnBase, dependentDerived.FindProperty("EnumDiscriminator")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase0, dependentDerived.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase1, dependentDerived.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)moneyColumnBase, dependentDerived.FindProperty("Money")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); - var tableMappings1 = new List(); - dependentDerived.SetRuntimeAnnotation("Relational:TableMappings", tableMappings1); + var tableMappings2 = new List(); + dependentDerived.SetRuntimeAnnotation("Relational:TableMappings", tableMappings2); var dependentBasebyteTableMapping0 = new TableMapping(dependentDerived, dependentBasebyteTable, null) { IsSharedTablePrincipal = false, }; dependentBasebyteTable.AddTypeMapping(dependentBasebyteTableMapping0, false); - tableMappings1.Add(dependentBasebyteTableMapping0); + tableMappings2.Add(dependentBasebyteTableMapping0); RelationalModel.CreateColumnMapping(principalAlternateIdColumn, dependentDerived.FindProperty("PrincipalAlternateId")!, dependentBasebyteTableMapping0); RelationalModel.CreateColumnMapping(principalIdColumn, dependentDerived.FindProperty("PrincipalId")!, dependentBasebyteTableMapping0); RelationalModel.CreateColumnMapping(dataColumn, dependentDerived.FindProperty("Data")!, dependentBasebyteTableMapping0); RelationalModel.CreateColumnMapping(enumDiscriminatorColumn, dependentDerived.FindProperty("EnumDiscriminator")!, dependentBasebyteTableMapping0); - RelationalModel.CreateColumnMapping(idColumn0, dependentDerived.FindProperty("Id")!, dependentBasebyteTableMapping0); + RelationalModel.CreateColumnMapping(idColumn1, dependentDerived.FindProperty("Id")!, dependentBasebyteTableMapping0); RelationalModel.CreateColumnMapping(moneyColumn, dependentDerived.FindProperty("Money")!, dependentBasebyteTableMapping0); var pK_DependentBasebyte = new UniqueConstraint("PK_DependentBase", dependentBasebyteTable, new[] { principalIdColumn, principalAlternateIdColumn }); dependentBasebyteTable.PrimaryKey = pK_DependentBasebyte; @@ -248,8 +297,8 @@ private IRelationalModel CreateRelationalModel() var manyTypes = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+ManyTypes")!; - var defaultTableMappings2 = new List>(); - manyTypes.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings2); + var defaultTableMappings3 = new List>(); + manyTypes.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings3); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase = new TableBase("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+ManyTypes", null, relationalModel); var boolColumnBase = new ColumnBase("Bool", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.Columns.Add("Bool", boolColumnBase); @@ -437,8 +486,8 @@ private IRelationalModel CreateRelationalModel() microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.Columns.Add("IPAddressToBytesConverterProperty", iPAddressToBytesConverterPropertyColumnBase); var iPAddressToStringConverterPropertyColumnBase = new ColumnBase("IPAddressToStringConverterProperty", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.Columns.Add("IPAddressToStringConverterProperty", iPAddressToStringConverterPropertyColumnBase); - var idColumnBase1 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); - microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.Columns.Add("Id", idColumnBase1); + var idColumnBase2 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); + microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.Columns.Add("Id", idColumnBase2); var int16ColumnBase = new ColumnBase("Int16", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.Columns.Add("Int16", int16ColumnBase); var int16ArrayColumnBase = new ColumnBase("Int16Array", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); @@ -859,8 +908,8 @@ private IRelationalModel CreateRelationalModel() relationalModel.DefaultTables.Add("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+ManyTypes", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase = new TableMappingBase(manyTypes, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase, false); - defaultTableMappings2.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase1, manyTypes.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); + defaultTableMappings3.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase2, manyTypes.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)boolColumnBase, manyTypes.FindProperty("Bool")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)boolArrayColumnBase, manyTypes.FindProperty("BoolArray")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)boolReadOnlyCollectionColumnBase, manyTypes.FindProperty("BoolReadOnlyCollection")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); @@ -1102,12 +1151,12 @@ private IRelationalModel CreateRelationalModel() RelationalModel.CreateColumnMapping((ColumnBase)uriArrayColumnBase, manyTypes.FindProperty("UriArray")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)uriToStringConverterPropertyColumnBase, manyTypes.FindProperty("UriToStringConverterProperty")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); - var tableMappings2 = new List(); - manyTypes.SetRuntimeAnnotation("Relational:TableMappings", tableMappings2); + var tableMappings3 = new List(); + manyTypes.SetRuntimeAnnotation("Relational:TableMappings", tableMappings3); var manyTypesTable = new Table("ManyTypes", null, relationalModel); - var idColumn1 = new Column("Id", "INTEGER", manyTypesTable); - manyTypesTable.Columns.Add("Id", idColumn1); - idColumn1.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn1); + var idColumn2 = new Column("Id", "INTEGER", manyTypesTable); + manyTypesTable.Columns.Add("Id", idColumn2); + idColumn2.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn2); var boolColumn = new Column("Bool", "INTEGER", manyTypesTable); manyTypesTable.Columns.Add("Bool", boolColumn); boolColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(boolColumn); @@ -1954,8 +2003,8 @@ private IRelationalModel CreateRelationalModel() relationalModel.Tables.Add(("ManyTypes", null), manyTypesTable); var manyTypesTableMapping = new TableMapping(manyTypes, manyTypesTable, null); manyTypesTable.AddTypeMapping(manyTypesTableMapping, false); - tableMappings2.Add(manyTypesTableMapping); - RelationalModel.CreateColumnMapping(idColumn1, manyTypes.FindProperty("Id")!, manyTypesTableMapping); + tableMappings3.Add(manyTypesTableMapping); + RelationalModel.CreateColumnMapping(idColumn2, manyTypes.FindProperty("Id")!, manyTypesTableMapping); RelationalModel.CreateColumnMapping(boolColumn, manyTypes.FindProperty("Bool")!, manyTypesTableMapping); RelationalModel.CreateColumnMapping(boolArrayColumn, manyTypes.FindProperty("BoolArray")!, manyTypesTableMapping); RelationalModel.CreateColumnMapping(boolReadOnlyCollectionColumn, manyTypes.FindProperty("BoolReadOnlyCollection")!, manyTypesTableMapping); @@ -2196,7 +2245,7 @@ private IRelationalModel CreateRelationalModel() RelationalModel.CreateColumnMapping(uriColumn, manyTypes.FindProperty("Uri")!, manyTypesTableMapping); RelationalModel.CreateColumnMapping(uriArrayColumn, manyTypes.FindProperty("UriArray")!, manyTypesTableMapping); RelationalModel.CreateColumnMapping(uriToStringConverterPropertyColumn, manyTypes.FindProperty("UriToStringConverterProperty")!, manyTypesTableMapping); - var pK_ManyTypes = new UniqueConstraint("PK_ManyTypes", manyTypesTable, new[] { idColumn1 }); + var pK_ManyTypes = new UniqueConstraint("PK_ManyTypes", manyTypesTable, new[] { idColumn2 }); manyTypesTable.PrimaryKey = pK_ManyTypes; pK_ManyTypes.SetRowKeyValueFactory(new SimpleRowKeyValueFactory(pK_ManyTypes)); var pK_ManyTypesKey = RelationalModel.GetKey(this, @@ -2208,8 +2257,8 @@ private IRelationalModel CreateRelationalModel() var principalBase = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase")!; - var defaultTableMappings3 = new List>(); - principalBase.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings3); + var defaultTableMappings4 = new List>(); + principalBase.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings4); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase = new TableBase("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", null, relationalModel); var alternateIdColumnBase = new ColumnBase("AlternateId", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.Columns.Add("AlternateId", alternateIdColumnBase); @@ -2229,8 +2278,8 @@ private IRelationalModel CreateRelationalModel() microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.Columns.Add("FlagsEnum1", flagsEnum1ColumnBase); var flagsEnum2ColumnBase = new ColumnBase("FlagsEnum2", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.Columns.Add("FlagsEnum2", flagsEnum2ColumnBase); - var idColumnBase2 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase); - microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.Columns.Add("Id", idColumnBase2); + var idColumnBase3 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase); + microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.Columns.Add("Id", idColumnBase3); var numberColumnBase = new ColumnBase("Number", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.Columns.Add("Number", numberColumnBase); var pointColumnBase0 = new ColumnBase("Point", "geometry", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase) @@ -2285,9 +2334,9 @@ private IRelationalModel CreateRelationalModel() relationalModel.DefaultTables.Add("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase = new TableMappingBase(principalBase, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase, true); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase, false); - defaultTableMappings3.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); + defaultTableMappings4.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)alternateIdColumnBase, principalBase.FindProperty("AlternateId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase2, principalBase.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase3, principalBase.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)enum1ColumnBase, principalBase.FindProperty("Enum1")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)enum2ColumnBase, principalBase.FindProperty("Enum2")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)flagsEnum1ColumnBase, principalBase.FindProperty("FlagsEnum1")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); @@ -2302,12 +2351,12 @@ private IRelationalModel CreateRelationalModel() RelationalModel.CreateColumnMapping((ColumnBase)valueTypeIListColumnBase, principalBase.FindProperty("ValueTypeIList")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)valueTypeListColumnBase, principalBase.FindProperty("ValueTypeList")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); - var tableMappings3 = new List(); - principalBase.SetRuntimeAnnotation("Relational:TableMappings", tableMappings3); + var tableMappings4 = new List(); + principalBase.SetRuntimeAnnotation("Relational:TableMappings", tableMappings4); var principalBaseTable = new Table("PrincipalBase", "mySchema", relationalModel); - var idColumn2 = new Column("Id", "INTEGER", principalBaseTable); - principalBaseTable.Columns.Add("Id", idColumn2); - idColumn2.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn2); + var idColumn3 = new Column("Id", "INTEGER", principalBaseTable); + principalBaseTable.Columns.Add("Id", idColumn3); + idColumn3.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn3); var alternateIdColumn = new Column("AlternateId", "TEXT", principalBaseTable); principalBaseTable.Columns.Add("AlternateId", alternateIdColumn); alternateIdColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(alternateIdColumn); @@ -2437,9 +2486,9 @@ private IRelationalModel CreateRelationalModel() IsSharedTablePrincipal = true, }; principalBaseTable.AddTypeMapping(principalBaseTableMapping, false); - tableMappings3.Add(principalBaseTableMapping); + tableMappings4.Add(principalBaseTableMapping); RelationalModel.CreateColumnMapping(alternateIdColumn, principalBase.FindProperty("AlternateId")!, principalBaseTableMapping); - RelationalModel.CreateColumnMapping(idColumn2, principalBase.FindProperty("Id")!, principalBaseTableMapping); + RelationalModel.CreateColumnMapping(idColumn3, principalBase.FindProperty("Id")!, principalBaseTableMapping); RelationalModel.CreateColumnMapping(enum1Column, principalBase.FindProperty("Enum1")!, principalBaseTableMapping); RelationalModel.CreateColumnMapping(enum2Column, principalBase.FindProperty("Enum2")!, principalBaseTableMapping); RelationalModel.CreateColumnMapping(flagsEnum1Column, principalBase.FindProperty("FlagsEnum1")!, principalBaseTableMapping); @@ -2456,11 +2505,11 @@ private IRelationalModel CreateRelationalModel() var ownedType = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase.Owned#OwnedType")!; - var defaultTableMappings4 = new List>(); - ownedType.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings4); + var defaultTableMappings5 = new List>(); + ownedType.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings5); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0 = new TableMappingBase(ownedType, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0, false); - defaultTableMappings4.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0); + defaultTableMappings5.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)principalBaseAlternateIdColumnBase, ownedType.FindProperty("PrincipalBaseAlternateId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)principalBaseIdColumnBase, ownedType.FindProperty("PrincipalBaseId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)detailsColumnBase, ownedType.FindProperty("Details")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0); @@ -2474,22 +2523,22 @@ private IRelationalModel CreateRelationalModel() RelationalModel.CreateColumnMapping((ColumnBase)valueTypeIListColumnBase, ownedType.FindProperty("ValueTypeIList")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)valueTypeListColumnBase, ownedType.FindProperty("ValueTypeList")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0); - var tableMappings4 = new List(); - ownedType.SetRuntimeAnnotation("Relational:TableMappings", tableMappings4); + var tableMappings5 = new List(); + ownedType.SetRuntimeAnnotation("Relational:TableMappings", tableMappings5); var principalBaseTableMapping0 = new TableMapping(ownedType, principalBaseTable, null) { IsSharedTablePrincipal = false, IsSplitEntityTypePrincipal = true }; principalBaseTable.AddTypeMapping(principalBaseTableMapping0, false); - tableMappings4.Add(principalBaseTableMapping0); + tableMappings5.Add(principalBaseTableMapping0); principalBaseTable.AddRowInternalForeignKey(ownedType, RelationalModel.GetForeignKey(this, "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase.Owned#OwnedType", new[] { "PrincipalBaseId", "PrincipalBaseAlternateId" }, "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", new[] { "Id", "AlternateId" })); RelationalModel.CreateColumnMapping(alternateIdColumn, ownedType.FindProperty("PrincipalBaseAlternateId")!, principalBaseTableMapping0); - RelationalModel.CreateColumnMapping(idColumn2, ownedType.FindProperty("PrincipalBaseId")!, principalBaseTableMapping0); + RelationalModel.CreateColumnMapping(idColumn3, ownedType.FindProperty("PrincipalBaseId")!, principalBaseTableMapping0); RelationalModel.CreateColumnMapping(owned_NumberColumn, ownedType.FindProperty("Number")!, principalBaseTableMapping0); RelationalModel.CreateColumnMapping(owned_RefTypeArrayColumn, ownedType.FindProperty("RefTypeArray")!, principalBaseTableMapping0); RelationalModel.CreateColumnMapping(owned_RefTypeEnumerableColumn, ownedType.FindProperty("RefTypeEnumerable")!, principalBaseTableMapping0); @@ -2518,7 +2567,7 @@ private IRelationalModel CreateRelationalModel() IsSplitEntityTypePrincipal = false }; detailsTable.AddTypeMapping(detailsTableMapping, false); - tableMappings4.Add(detailsTableMapping); + tableMappings5.Add(detailsTableMapping); RelationalModel.CreateColumnMapping(principalBaseAlternateIdColumn, ownedType.FindProperty("PrincipalBaseAlternateId")!, detailsTableMapping); RelationalModel.CreateColumnMapping(principalBaseIdColumn, ownedType.FindProperty("PrincipalBaseId")!, detailsTableMapping); RelationalModel.CreateColumnMapping(detailsColumn, ownedType.FindProperty("Details")!, detailsTableMapping); @@ -2534,13 +2583,13 @@ private IRelationalModel CreateRelationalModel() var principalDerived = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>")!; - var defaultTableMappings5 = new List>(); - principalDerived.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings5); + var defaultTableMappings6 = new List>(); + principalDerived.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings6); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1 = new TableMappingBase(principalDerived, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1, false); - defaultTableMappings5.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); + defaultTableMappings6.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); RelationalModel.CreateColumnMapping((ColumnBase)alternateIdColumnBase, principalDerived.FindProperty("AlternateId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase2, principalDerived.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase3, principalDerived.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); RelationalModel.CreateColumnMapping((ColumnBase)enum1ColumnBase, principalDerived.FindProperty("Enum1")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); RelationalModel.CreateColumnMapping((ColumnBase)enum2ColumnBase, principalDerived.FindProperty("Enum2")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); RelationalModel.CreateColumnMapping((ColumnBase)flagsEnum1ColumnBase, principalDerived.FindProperty("FlagsEnum1")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); @@ -2557,25 +2606,25 @@ private IRelationalModel CreateRelationalModel() var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase = new TableBase("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>", null, relationalModel); var alternateIdColumnBase0 = new ColumnBase("AlternateId", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.Columns.Add("AlternateId", alternateIdColumnBase0); - var idColumnBase3 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase); - microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.Columns.Add("Id", idColumnBase3); + var idColumnBase4 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase); + microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.Columns.Add("Id", idColumnBase4); relationalModel.DefaultTables.Add("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase = new TableMappingBase(principalDerived, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase, false); - defaultTableMappings5.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); + defaultTableMappings6.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)alternateIdColumnBase0, principalDerived.FindProperty("AlternateId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase3, principalDerived.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase4, principalDerived.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); - var tableMappings5 = new List(); - principalDerived.SetRuntimeAnnotation("Relational:TableMappings", tableMappings5); + var tableMappings6 = new List(); + principalDerived.SetRuntimeAnnotation("Relational:TableMappings", tableMappings6); var principalBaseTableMapping1 = new TableMapping(principalDerived, principalBaseTable, null) { IsSharedTablePrincipal = false, }; principalBaseTable.AddTypeMapping(principalBaseTableMapping1, false); - tableMappings5.Add(principalBaseTableMapping1); + tableMappings6.Add(principalBaseTableMapping1); RelationalModel.CreateColumnMapping(alternateIdColumn, principalDerived.FindProperty("AlternateId")!, principalBaseTableMapping1); - RelationalModel.CreateColumnMapping(idColumn2, principalDerived.FindProperty("Id")!, principalBaseTableMapping1); + RelationalModel.CreateColumnMapping(idColumn3, principalDerived.FindProperty("Id")!, principalBaseTableMapping1); RelationalModel.CreateColumnMapping(enum1Column, principalDerived.FindProperty("Enum1")!, principalBaseTableMapping1); RelationalModel.CreateColumnMapping(enum2Column, principalDerived.FindProperty("Enum2")!, principalBaseTableMapping1); RelationalModel.CreateColumnMapping(flagsEnum1Column, principalDerived.FindProperty("FlagsEnum1")!, principalBaseTableMapping1); @@ -2589,7 +2638,7 @@ private IRelationalModel CreateRelationalModel() RelationalModel.CreateColumnMapping(valueTypeEnumerableColumn, principalDerived.FindProperty("ValueTypeEnumerable")!, principalBaseTableMapping1); RelationalModel.CreateColumnMapping(valueTypeIListColumn, principalDerived.FindProperty("ValueTypeIList")!, principalBaseTableMapping1); RelationalModel.CreateColumnMapping(valueTypeListColumn, principalDerived.FindProperty("ValueTypeList")!, principalBaseTableMapping1); - var aK_PrincipalBase_Id = new UniqueConstraint("AK_PrincipalBase_Id", principalBaseTable, new[] { idColumn2 }); + var aK_PrincipalBase_Id = new UniqueConstraint("AK_PrincipalBase_Id", principalBaseTable, new[] { idColumn3 }); aK_PrincipalBase_Id.SetRowKeyValueFactory(new SimpleRowKeyValueFactory(aK_PrincipalBase_Id)); var aK_PrincipalBase_IdKey = RelationalModel.GetKey(this, "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", @@ -2597,7 +2646,7 @@ private IRelationalModel CreateRelationalModel() aK_PrincipalBase_Id.MappedKeys.Add(aK_PrincipalBase_IdKey); RelationalModel.GetOrCreateUniqueConstraints(aK_PrincipalBase_IdKey).Add(aK_PrincipalBase_Id); principalBaseTable.UniqueConstraints.Add("AK_PrincipalBase_Id", aK_PrincipalBase_Id); - var pK = new UniqueConstraint("PK", principalBaseTable, new[] { idColumn2, alternateIdColumn }); + var pK = new UniqueConstraint("PK", principalBaseTable, new[] { idColumn3, alternateIdColumn }); principalBaseTable.PrimaryKey = pK; pK.SetRowKeyValueFactory(new CompositeRowKeyValueFactory(pK)); var pKKey = RelationalModel.GetKey(this, @@ -2609,7 +2658,7 @@ private IRelationalModel CreateRelationalModel() RelationalModel.GetOrCreateUniqueConstraints(pK_DetailsKey).Add(pK); principalBaseTable.UniqueConstraints.Add("PK", pK); var iX_PrincipalBase_AlternateId_Id = new TableIndex( - "IX_PrincipalBase_AlternateId_Id", principalBaseTable, new[] { alternateIdColumn, idColumn2 }, false); + "IX_PrincipalBase_AlternateId_Id", principalBaseTable, new[] { alternateIdColumn, idColumn3 }, false); iX_PrincipalBase_AlternateId_Id.SetRowIndexValueFactory(new CompositeRowIndexValueFactory(iX_PrincipalBase_AlternateId_Id)); var iX_PrincipalBase_AlternateId_IdIx = RelationalModel.GetIndex(this, "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", @@ -2627,7 +2676,7 @@ private IRelationalModel CreateRelationalModel() relationalModel.Tables.Add(("PrincipalDerived", null), principalDerivedTable); var principalDerivedTableMapping = new TableMapping(principalDerived, principalDerivedTable, null); principalDerivedTable.AddTypeMapping(principalDerivedTableMapping, false); - tableMappings5.Add(principalDerivedTableMapping); + tableMappings6.Add(principalDerivedTableMapping); RelationalModel.CreateColumnMapping(alternateIdColumn0, principalDerived.FindProperty("AlternateId")!, principalDerivedTableMapping); RelationalModel.CreateColumnMapping(derivedIdColumn, principalDerived.FindProperty("Id")!, principalDerivedTableMapping); var aK_PrincipalDerived_DerivedId = new UniqueConstraint("AK_PrincipalDerived_DerivedId", principalDerivedTable, new[] { derivedIdColumn }); @@ -2650,16 +2699,16 @@ private IRelationalModel CreateRelationalModel() var ownedType0 = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>.ManyOwned#OwnedType")!; - var defaultTableMappings6 = new List>(); - ownedType0.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings6); + var defaultTableMappings7 = new List>(); + ownedType0.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings7); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase = new TableBase("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>.ManyOwned#OwnedType", null, relationalModel); var detailsColumnBase0 = new ColumnBase("Details", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase) { IsNullable = true }; microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase.Columns.Add("Details", detailsColumnBase0); - var idColumnBase4 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase); - microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase.Columns.Add("Id", idColumnBase4); + var idColumnBase5 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase); + microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase.Columns.Add("Id", idColumnBase5); var numberColumnBase0 = new ColumnBase("Number", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase.Columns.Add("Number", numberColumnBase0); var principalDerivedDependentBasebyteAlternateIdColumnBase = new ColumnBase("PrincipalDerived>AlternateId", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase); @@ -2709,8 +2758,8 @@ private IRelationalModel CreateRelationalModel() relationalModel.DefaultTables.Add("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>.ManyOwned#OwnedType", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeMappingBase = new TableMappingBase(ownedType0, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeMappingBase, false); - defaultTableMappings6.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeMappingBase); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase4, ownedType0.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeMappingBase); + defaultTableMappings7.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase5, ownedType0.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)principalDerivedDependentBasebyteAlternateIdColumnBase, ownedType0.FindProperty("PrincipalDerivedAlternateId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)principalDerivedDependentBasebyteIdColumnBase, ownedType0.FindProperty("PrincipalDerivedId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)detailsColumnBase0, ownedType0.FindProperty("Details")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeMappingBase); @@ -2724,8 +2773,8 @@ private IRelationalModel CreateRelationalModel() RelationalModel.CreateColumnMapping((ColumnBase)valueTypeIListColumnBase0, ownedType0.FindProperty("ValueTypeIList")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)valueTypeListColumnBase0, ownedType0.FindProperty("ValueTypeList")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalDerivedMicrosoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteManyOwnedOwnedTypeMappingBase); - var tableMappings6 = new List(); - ownedType0.SetRuntimeAnnotation("Relational:TableMappings", tableMappings6); + var tableMappings7 = new List(); + ownedType0.SetRuntimeAnnotation("Relational:TableMappings", tableMappings7); var manyOwnedTable = new Table("ManyOwned", null, relationalModel); var principalDerivedDependentBasebyteIdColumn = new Column("PrincipalDerived>Id", "INTEGER", manyOwnedTable); manyOwnedTable.Columns.Add("PrincipalDerived>Id", principalDerivedDependentBasebyteIdColumn); @@ -2733,9 +2782,9 @@ private IRelationalModel CreateRelationalModel() var principalDerivedDependentBasebyteAlternateIdColumn = new Column("PrincipalDerived>AlternateId", "TEXT", manyOwnedTable); manyOwnedTable.Columns.Add("PrincipalDerived>AlternateId", principalDerivedDependentBasebyteAlternateIdColumn); principalDerivedDependentBasebyteAlternateIdColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(principalDerivedDependentBasebyteAlternateIdColumn); - var idColumn3 = new Column("Id", "INTEGER", manyOwnedTable); - manyOwnedTable.Columns.Add("Id", idColumn3); - idColumn3.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn3); + var idColumn4 = new Column("Id", "INTEGER", manyOwnedTable); + manyOwnedTable.Columns.Add("Id", idColumn4); + idColumn4.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn4); var detailsColumn0 = new Column("Details", "TEXT", manyOwnedTable) { IsNullable = true @@ -2796,8 +2845,8 @@ private IRelationalModel CreateRelationalModel() relationalModel.Tables.Add(("ManyOwned", null), manyOwnedTable); var manyOwnedTableMapping = new TableMapping(ownedType0, manyOwnedTable, null); manyOwnedTable.AddTypeMapping(manyOwnedTableMapping, false); - tableMappings6.Add(manyOwnedTableMapping); - RelationalModel.CreateColumnMapping(idColumn3, ownedType0.FindProperty("Id")!, manyOwnedTableMapping); + tableMappings7.Add(manyOwnedTableMapping); + RelationalModel.CreateColumnMapping(idColumn4, ownedType0.FindProperty("Id")!, manyOwnedTableMapping); RelationalModel.CreateColumnMapping(principalDerivedDependentBasebyteAlternateIdColumn, ownedType0.FindProperty("PrincipalDerivedAlternateId")!, manyOwnedTableMapping); RelationalModel.CreateColumnMapping(principalDerivedDependentBasebyteIdColumn, ownedType0.FindProperty("PrincipalDerivedId")!, manyOwnedTableMapping); RelationalModel.CreateColumnMapping(detailsColumn0, ownedType0.FindProperty("Details")!, manyOwnedTableMapping); @@ -2810,7 +2859,7 @@ private IRelationalModel CreateRelationalModel() RelationalModel.CreateColumnMapping(valueTypeEnumerableColumn0, ownedType0.FindProperty("ValueTypeEnumerable")!, manyOwnedTableMapping); RelationalModel.CreateColumnMapping(valueTypeIListColumn0, ownedType0.FindProperty("ValueTypeIList")!, manyOwnedTableMapping); RelationalModel.CreateColumnMapping(valueTypeListColumn0, ownedType0.FindProperty("ValueTypeList")!, manyOwnedTableMapping); - var pK_ManyOwned = new UniqueConstraint("PK_ManyOwned", manyOwnedTable, new[] { principalDerivedDependentBasebyteIdColumn, principalDerivedDependentBasebyteAlternateIdColumn, idColumn3 }); + var pK_ManyOwned = new UniqueConstraint("PK_ManyOwned", manyOwnedTable, new[] { principalDerivedDependentBasebyteIdColumn, principalDerivedDependentBasebyteAlternateIdColumn, idColumn4 }); manyOwnedTable.PrimaryKey = pK_ManyOwned; pK_ManyOwned.SetRowKeyValueFactory(new CompositeRowKeyValueFactory(pK_ManyOwned)); var pK_ManyOwnedKey = RelationalModel.GetKey(this, @@ -2822,8 +2871,8 @@ private IRelationalModel CreateRelationalModel() var principalBasePrincipalDerivedDependentBasebyte = FindEntityType("PrincipalBasePrincipalDerived>")!; - var defaultTableMappings7 = new List>(); - principalBasePrincipalDerivedDependentBasebyte.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings7); + var defaultTableMappings8 = new List>(); + principalBasePrincipalDerivedDependentBasebyte.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings8); var principalBasePrincipalDerivedDependentBasebyteTableBase = new TableBase("PrincipalBasePrincipalDerived>", null, relationalModel); var derivedsAlternateIdColumnBase = new ColumnBase("DerivedsAlternateId", "TEXT", principalBasePrincipalDerivedDependentBasebyteTableBase); principalBasePrincipalDerivedDependentBasebyteTableBase.Columns.Add("DerivedsAlternateId", derivedsAlternateIdColumnBase); @@ -2841,15 +2890,15 @@ private IRelationalModel CreateRelationalModel() relationalModel.DefaultTables.Add("PrincipalBasePrincipalDerived>", principalBasePrincipalDerivedDependentBasebyteTableBase); var principalBasePrincipalDerivedDependentBasebyteMappingBase = new TableMappingBase(principalBasePrincipalDerivedDependentBasebyte, principalBasePrincipalDerivedDependentBasebyteTableBase, null); principalBasePrincipalDerivedDependentBasebyteTableBase.AddTypeMapping(principalBasePrincipalDerivedDependentBasebyteMappingBase, false); - defaultTableMappings7.Add(principalBasePrincipalDerivedDependentBasebyteMappingBase); + defaultTableMappings8.Add(principalBasePrincipalDerivedDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)derivedsAlternateIdColumnBase, principalBasePrincipalDerivedDependentBasebyte.FindProperty("DerivedsAlternateId")!, principalBasePrincipalDerivedDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)derivedsIdColumnBase, principalBasePrincipalDerivedDependentBasebyte.FindProperty("DerivedsId")!, principalBasePrincipalDerivedDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)principalsAlternateIdColumnBase, principalBasePrincipalDerivedDependentBasebyte.FindProperty("PrincipalsAlternateId")!, principalBasePrincipalDerivedDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)principalsIdColumnBase, principalBasePrincipalDerivedDependentBasebyte.FindProperty("PrincipalsId")!, principalBasePrincipalDerivedDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)rowidColumnBase, principalBasePrincipalDerivedDependentBasebyte.FindProperty("rowid")!, principalBasePrincipalDerivedDependentBasebyteMappingBase); - var tableMappings7 = new List(); - principalBasePrincipalDerivedDependentBasebyte.SetRuntimeAnnotation("Relational:TableMappings", tableMappings7); + var tableMappings8 = new List(); + principalBasePrincipalDerivedDependentBasebyte.SetRuntimeAnnotation("Relational:TableMappings", tableMappings8); var principalBasePrincipalDerivedDependentBasebyteTable = new Table("PrincipalBasePrincipalDerived>", null, relationalModel); var derivedsIdColumn = new Column("DerivedsId", "INTEGER", principalBasePrincipalDerivedDependentBasebyteTable); principalBasePrincipalDerivedDependentBasebyteTable.Columns.Add("DerivedsId", derivedsIdColumn); @@ -2872,7 +2921,7 @@ private IRelationalModel CreateRelationalModel() relationalModel.Tables.Add(("PrincipalBasePrincipalDerived>", null), principalBasePrincipalDerivedDependentBasebyteTable); var principalBasePrincipalDerivedDependentBasebyteTableMapping = new TableMapping(principalBasePrincipalDerivedDependentBasebyte, principalBasePrincipalDerivedDependentBasebyteTable, null); principalBasePrincipalDerivedDependentBasebyteTable.AddTypeMapping(principalBasePrincipalDerivedDependentBasebyteTableMapping, false); - tableMappings7.Add(principalBasePrincipalDerivedDependentBasebyteTableMapping); + tableMappings8.Add(principalBasePrincipalDerivedDependentBasebyteTableMapping); RelationalModel.CreateColumnMapping(derivedsAlternateIdColumn, principalBasePrincipalDerivedDependentBasebyte.FindProperty("DerivedsAlternateId")!, principalBasePrincipalDerivedDependentBasebyteTableMapping); RelationalModel.CreateColumnMapping(derivedsIdColumn, principalBasePrincipalDerivedDependentBasebyte.FindProperty("DerivedsId")!, principalBasePrincipalDerivedDependentBasebyteTableMapping); RelationalModel.CreateColumnMapping(principalsAlternateIdColumn, principalBasePrincipalDerivedDependentBasebyte.FindProperty("PrincipalsAlternateId")!, principalBasePrincipalDerivedDependentBasebyteTableMapping); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/AutoIncrementEntityEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/AutoIncrementEntityEntityType.cs new file mode 100644 index 00000000000..93394873614 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/AutoIncrementEntityEntityType.cs @@ -0,0 +1,171 @@ +// +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Scaffolding; +using Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal; +using Microsoft.EntityFrameworkCore.Storage; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class AutoIncrementEntityEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelSqliteTest+AutoIncrementEntity", + typeof(CompiledModelSqliteTest.AutoIncrementEntity), + baseEntityType, + propertyCount: 2, + keyCount: 1); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(int), + propertyInfo: typeof(CompiledModelSqliteTest.AutoIncrementEntity).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelSqliteTest.AutoIncrementEntity).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0); + id.SetGetter( + int (CompiledModelSqliteTest.AutoIncrementEntity instance) => AutoIncrementEntityUnsafeAccessors.Id(instance), + bool (CompiledModelSqliteTest.AutoIncrementEntity instance) => AutoIncrementEntityUnsafeAccessors.Id(instance) == 0); + id.SetSetter( + CompiledModelSqliteTest.AutoIncrementEntity (CompiledModelSqliteTest.AutoIncrementEntity instance, int value) => + { + AutoIncrementEntityUnsafeAccessors.Id(instance) = value; + return instance; + }); + id.SetMaterializationSetter( + CompiledModelSqliteTest.AutoIncrementEntity (CompiledModelSqliteTest.AutoIncrementEntity instance, int value) => + { + AutoIncrementEntityUnsafeAccessors.Id(instance) = value; + return instance; + }); + id.SetAccessors( + int (IInternalEntry entry) => (entry.FlaggedAsStoreGenerated(0) ? entry.ReadStoreGeneratedValue(0) : (entry.FlaggedAsTemporary(0) && AutoIncrementEntityUnsafeAccessors.Id(((CompiledModelSqliteTest.AutoIncrementEntity)(entry.Entity))) == 0 ? entry.ReadTemporaryValue(0) : AutoIncrementEntityUnsafeAccessors.Id(((CompiledModelSqliteTest.AutoIncrementEntity)(entry.Entity))))), + int (IInternalEntry entry) => AutoIncrementEntityUnsafeAccessors.Id(((CompiledModelSqliteTest.AutoIncrementEntity)(entry.Entity))), + int (IInternalEntry entry) => entry.ReadOriginalValue(id, 0), + int (IInternalEntry entry) => ((InternalEntityEntry)(entry)).ReadRelationshipSnapshotValue(id, 0)); + id.SetPropertyIndexes( + index: 0, + originalValueIndex: 0, + shadowIndex: -1, + relationshipIndex: 0, + storeGenerationIndex: 0); + id.TypeMapping = IntTypeMapping.Default.Clone( + comparer: new ValueComparer( + bool (int v1, int v2) => v1 == v2, + int (int v) => v, + int (int v) => v), + keyComparer: new ValueComparer( + bool (int v1, int v2) => v1 == v2, + int (int v) => v, + int (int v) => v), + providerValueComparer: new ValueComparer( + bool (int v1, int v2) => v1 == v2, + int (int v) => v, + int (int v) => v), + mappingInfo: new RelationalTypeMappingInfo( + storeTypeName: "INTEGER")); + id.SetCurrentValueComparer(new EntryCurrentValueComparer(id)); + + var name = runtimeEntityType.AddProperty( + "Name", + typeof(string), + propertyInfo: typeof(CompiledModelSqliteTest.AutoIncrementEntity).GetProperty("Name", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelSqliteTest.AutoIncrementEntity).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + name.SetGetter( + string (CompiledModelSqliteTest.AutoIncrementEntity instance) => AutoIncrementEntityUnsafeAccessors.Name(instance), + bool (CompiledModelSqliteTest.AutoIncrementEntity instance) => AutoIncrementEntityUnsafeAccessors.Name(instance) == null); + name.SetSetter( + CompiledModelSqliteTest.AutoIncrementEntity (CompiledModelSqliteTest.AutoIncrementEntity instance, string value) => + { + AutoIncrementEntityUnsafeAccessors.Name(instance) = value; + return instance; + }); + name.SetMaterializationSetter( + CompiledModelSqliteTest.AutoIncrementEntity (CompiledModelSqliteTest.AutoIncrementEntity instance, string value) => + { + AutoIncrementEntityUnsafeAccessors.Name(instance) = value; + return instance; + }); + name.SetAccessors( + string (IInternalEntry entry) => AutoIncrementEntityUnsafeAccessors.Name(((CompiledModelSqliteTest.AutoIncrementEntity)(entry.Entity))), + string (IInternalEntry entry) => AutoIncrementEntityUnsafeAccessors.Name(((CompiledModelSqliteTest.AutoIncrementEntity)(entry.Entity))), + string (IInternalEntry entry) => entry.ReadOriginalValue(name, 1), + string (IInternalEntry entry) => entry.GetCurrentValue(name)); + name.SetPropertyIndexes( + index: 1, + originalValueIndex: 1, + shadowIndex: -1, + relationshipIndex: -1, + storeGenerationIndex: -1); + name.TypeMapping = SqliteStringTypeMapping.Default; + + var key = runtimeEntityType.AddKey( + new[] { id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + var id = runtimeEntityType.FindProperty("Id"); + var name = runtimeEntityType.FindProperty("Name"); + var key = runtimeEntityType.FindKey(new[] { id }); + key.SetPrincipalKeyValueFactory(KeyValueFactoryFactory.CreateSimpleNonNullableFactory(key)); + key.SetIdentityMapFactory(IdentityMapFactoryFactory.CreateFactory(key)); + runtimeEntityType.SetOriginalValuesFactory( + ISnapshot (IInternalEntry source) => + { + var structuralType = ((CompiledModelSqliteTest.AutoIncrementEntity)(source.Entity)); + return ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)id).GetValueComparer())).Snapshot(source.GetCurrentValue(id)), (source.GetCurrentValue(name) == null ? null : ((ValueComparer)(((IProperty)name).GetValueComparer())).Snapshot(source.GetCurrentValue(name)))))); + }); + runtimeEntityType.SetStoreGeneratedValuesFactory( + ISnapshot () => ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)id).GetValueComparer())).Snapshot(default(int)))))); + runtimeEntityType.SetTemporaryValuesFactory( + ISnapshot (IInternalEntry source) => ((ISnapshot)(new Snapshot(default(int))))); + runtimeEntityType.SetShadowValuesFactory( + ISnapshot (IDictionary source) => Snapshot.Empty); + runtimeEntityType.SetEmptyShadowValuesFactory( + ISnapshot () => Snapshot.Empty); + runtimeEntityType.SetRelationshipSnapshotFactory( + ISnapshot (IInternalEntry source) => + { + var structuralType = ((CompiledModelSqliteTest.AutoIncrementEntity)(source.Entity)); + return ((ISnapshot)(new Snapshot(((ValueComparer)(((IProperty)id).GetKeyValueComparer())).Snapshot(source.GetCurrentValue(id))))); + }); + runtimeEntityType.SetCounts(new PropertyCounts( + propertyCount: 2, + navigationCount: 0, + complexPropertyCount: 0, + complexCollectionCount: 0, + originalValueCount: 2, + shadowCount: 0, + relationshipCount: 1, + storeGeneratedCount: 1)); + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "AutoIncrementEntity"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/AutoIncrementEntityUnsafeAccessors.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/AutoIncrementEntityUnsafeAccessors.cs new file mode 100644 index 00000000000..536893c1d93 --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/AutoIncrementEntityUnsafeAccessors.cs @@ -0,0 +1,19 @@ +// +using System; +using System.Runtime.CompilerServices; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + public static class AutoIncrementEntityUnsafeAccessors + { + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "k__BackingField")] + public static extern ref int Id(CompiledModelSqliteTest.AutoIncrementEntity @this); + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = "k__BackingField")] + public static extern ref string Name(CompiledModelSqliteTest.AutoIncrementEntity @this); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DbContextModelBuilder.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DbContextModelBuilder.cs index a780c188b8f..1f2fce175df 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DbContextModelBuilder.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/BigModel_with_JSON_columns/DbContextModelBuilder.cs @@ -18,12 +18,13 @@ namespace TestNamespace public partial class DbContextModel { private DbContextModel() - : base(skipDetectChanges: false, modelId: new Guid("00000000-0000-0000-0000-000000000000"), entityTypeCount: 9) + : base(skipDetectChanges: false, modelId: new Guid("00000000-0000-0000-0000-000000000000"), entityTypeCount: 10) { } partial void Initialize() { + var autoIncrementEntity = AutoIncrementEntityEntityType.Create(this); var data = DataEntityType.Create(this); var dependentBase = DependentBaseEntityType.Create(this); var manyTypes = ManyTypesEntityType.Create(this); @@ -44,6 +45,7 @@ partial void Initialize() PrincipalBaseEntityType.CreateSkipNavigation1(principalBase, principalDerived, principalBasePrincipalDerivedDependentBasebyte); PrincipalDerivedEntityType.CreateSkipNavigation1(principalDerived, principalBase, principalBasePrincipalDerivedDependentBasebyte); + AutoIncrementEntityEntityType.CreateAnnotations(autoIncrementEntity); DataEntityType.CreateAnnotations(data); DependentBaseEntityType.CreateAnnotations(dependentBase); ManyTypesEntityType.CreateAnnotations(manyTypes); @@ -61,18 +63,65 @@ private IRelationalModel CreateRelationalModel() { var relationalModel = new RelationalModel(this); - var data = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+Data")!; + var autoIncrementEntity = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelSqliteTest+AutoIncrementEntity")!; var defaultTableMappings = new List>(); - data.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings); + autoIncrementEntity.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings); + var microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase = new TableBase("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelSqliteTest+AutoIncrementEntity", null, relationalModel); + var idColumnBase = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase); + microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase.Columns.Add("Id", idColumnBase); + var nameColumnBase = new ColumnBase("Name", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase) + { + IsNullable = true + }; + microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase.Columns.Add("Name", nameColumnBase); + relationalModel.DefaultTables.Add("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelSqliteTest+AutoIncrementEntity", microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase); + var microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityMappingBase = new TableMappingBase(autoIncrementEntity, microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase, null); + microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityMappingBase, false); + defaultTableMappings.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase, autoIncrementEntity.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)nameColumnBase, autoIncrementEntity.FindProperty("Name")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelSqliteTestAutoIncrementEntityMappingBase); + + var tableMappings = new List(); + autoIncrementEntity.SetRuntimeAnnotation("Relational:TableMappings", tableMappings); + var autoIncrementEntityTable = new Table("AutoIncrementEntity", null, relationalModel); + var idColumn = new Column("Id", "INTEGER", autoIncrementEntityTable); + autoIncrementEntityTable.Columns.Add("Id", idColumn); + idColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn); + var nameColumn = new Column("Name", "TEXT", autoIncrementEntityTable) + { + IsNullable = true + }; + autoIncrementEntityTable.Columns.Add("Name", nameColumn); + nameColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(nameColumn); + relationalModel.Tables.Add(("AutoIncrementEntity", null), autoIncrementEntityTable); + var autoIncrementEntityTableMapping = new TableMapping(autoIncrementEntity, autoIncrementEntityTable, null); + autoIncrementEntityTable.AddTypeMapping(autoIncrementEntityTableMapping, false); + tableMappings.Add(autoIncrementEntityTableMapping); + RelationalModel.CreateColumnMapping(idColumn, autoIncrementEntity.FindProperty("Id")!, autoIncrementEntityTableMapping); + RelationalModel.CreateColumnMapping(nameColumn, autoIncrementEntity.FindProperty("Name")!, autoIncrementEntityTableMapping); + var pK_AutoIncrementEntity = new UniqueConstraint("PK_AutoIncrementEntity", autoIncrementEntityTable, new[] { idColumn }); + autoIncrementEntityTable.PrimaryKey = pK_AutoIncrementEntity; + pK_AutoIncrementEntity.SetRowKeyValueFactory(new SimpleRowKeyValueFactory(pK_AutoIncrementEntity)); + var pK_AutoIncrementEntityKey = RelationalModel.GetKey(this, + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelSqliteTest+AutoIncrementEntity", + new[] { "Id" }); + pK_AutoIncrementEntity.MappedKeys.Add(pK_AutoIncrementEntityKey); + RelationalModel.GetOrCreateUniqueConstraints(pK_AutoIncrementEntityKey).Add(pK_AutoIncrementEntity); + autoIncrementEntityTable.UniqueConstraints.Add("PK_AutoIncrementEntity", pK_AutoIncrementEntity); + + var data = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+Data")!; + + var defaultTableMappings0 = new List>(); + data.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings0); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase = new TableBase("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+Data", null, relationalModel); var blobColumnBase = new ColumnBase("Blob", "BLOB", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase) { IsNullable = true }; microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase.Columns.Add("Blob", blobColumnBase); - var idColumnBase = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase); - microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase.Columns.Add("Id", idColumnBase); + var idColumnBase0 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase); + microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase.Columns.Add("Id", idColumnBase0); var pointColumnBase = new ColumnBase("Point", "POINT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase) { IsNullable = true @@ -81,17 +130,17 @@ private IRelationalModel CreateRelationalModel() relationalModel.DefaultTables.Add("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+Data", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase = new TableMappingBase(data, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase, false); - defaultTableMappings.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase, data.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase); + defaultTableMappings0.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase0, data.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)blobColumnBase, data.FindProperty("Blob")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)pointColumnBase, data.FindProperty("Point")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDataMappingBase); - var tableMappings = new List(); - data.SetRuntimeAnnotation("Relational:TableMappings", tableMappings); + var tableMappings0 = new List(); + data.SetRuntimeAnnotation("Relational:TableMappings", tableMappings0); var dataTable = new Table("Data", null, relationalModel); - var idColumn = new Column("Id", "INTEGER", dataTable); - dataTable.Columns.Add("Id", idColumn); - idColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn); + var idColumn0 = new Column("Id", "INTEGER", dataTable); + dataTable.Columns.Add("Id", idColumn0); + idColumn0.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn0); var blobColumn = new Column("Blob", "BLOB", dataTable) { IsNullable = true @@ -107,11 +156,11 @@ private IRelationalModel CreateRelationalModel() relationalModel.Tables.Add(("Data", null), dataTable); var dataTableMapping = new TableMapping(data, dataTable, null); dataTable.AddTypeMapping(dataTableMapping, false); - tableMappings.Add(dataTableMapping); - RelationalModel.CreateColumnMapping(idColumn, data.FindProperty("Id")!, dataTableMapping); + tableMappings0.Add(dataTableMapping); + RelationalModel.CreateColumnMapping(idColumn0, data.FindProperty("Id")!, dataTableMapping); RelationalModel.CreateColumnMapping(blobColumn, data.FindProperty("Blob")!, dataTableMapping); RelationalModel.CreateColumnMapping(pointColumn, data.FindProperty("Point")!, dataTableMapping); - var pK_Data = new UniqueConstraint("PK_Data", dataTable, new[] { idColumn }); + var pK_Data = new UniqueConstraint("PK_Data", dataTable, new[] { idColumn0 }); dataTable.PrimaryKey = pK_Data; pK_Data.SetRowKeyValueFactory(new SimpleRowKeyValueFactory(pK_Data)); var pK_DataKey = RelationalModel.GetKey(this, @@ -123,8 +172,8 @@ private IRelationalModel CreateRelationalModel() var dependentBase = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentBase")!; - var defaultTableMappings0 = new List>(); - dependentBase.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings0); + var defaultTableMappings1 = new List>(); + dependentBase.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings1); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase = new TableBase("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentBase", null, relationalModel); var dataColumnBase = new ColumnBase("Data", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase) { @@ -133,11 +182,11 @@ private IRelationalModel CreateRelationalModel() microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.Columns.Add("Data", dataColumnBase); var enumDiscriminatorColumnBase = new ColumnBase("EnumDiscriminator", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.Columns.Add("EnumDiscriminator", enumDiscriminatorColumnBase); - var idColumnBase0 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase) + var idColumnBase1 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase) { IsNullable = true }; - microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.Columns.Add("Id", idColumnBase0); + microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.Columns.Add("Id", idColumnBase1); var moneyColumnBase = new ColumnBase("Money", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase) { IsNullable = true @@ -150,14 +199,14 @@ private IRelationalModel CreateRelationalModel() relationalModel.DefaultTables.Add("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentBase", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase = new TableMappingBase(dependentBase, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase, true); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase, false); - defaultTableMappings0.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); + defaultTableMappings1.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)principalAlternateIdColumnBase, dependentBase.FindProperty("PrincipalAlternateId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)principalIdColumnBase, dependentBase.FindProperty("PrincipalId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)enumDiscriminatorColumnBase, dependentBase.FindProperty("EnumDiscriminator")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase0, dependentBase.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase1, dependentBase.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase); - var tableMappings0 = new List(); - dependentBase.SetRuntimeAnnotation("Relational:TableMappings", tableMappings0); + var tableMappings1 = new List(); + dependentBase.SetRuntimeAnnotation("Relational:TableMappings", tableMappings1); var dependentBasebyteTable = new Table("DependentBase", null, relationalModel); var principalIdColumn = new Column("PrincipalId", "INTEGER", dependentBasebyteTable); dependentBasebyteTable.Columns.Add("PrincipalId", principalIdColumn); @@ -174,12 +223,12 @@ private IRelationalModel CreateRelationalModel() var enumDiscriminatorColumn = new Column("EnumDiscriminator", "INTEGER", dependentBasebyteTable); dependentBasebyteTable.Columns.Add("EnumDiscriminator", enumDiscriminatorColumn); enumDiscriminatorColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(enumDiscriminatorColumn); - var idColumn0 = new Column("Id", "INTEGER", dependentBasebyteTable) + var idColumn1 = new Column("Id", "INTEGER", dependentBasebyteTable) { IsNullable = true }; - dependentBasebyteTable.Columns.Add("Id", idColumn0); - idColumn0.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn0); + dependentBasebyteTable.Columns.Add("Id", idColumn1); + idColumn1.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn1); var moneyColumn = new Column("Money", "TEXT", dependentBasebyteTable) { IsNullable = true @@ -192,39 +241,39 @@ private IRelationalModel CreateRelationalModel() IsSharedTablePrincipal = true, }; dependentBasebyteTable.AddTypeMapping(dependentBasebyteTableMapping, false); - tableMappings0.Add(dependentBasebyteTableMapping); + tableMappings1.Add(dependentBasebyteTableMapping); RelationalModel.CreateColumnMapping(principalAlternateIdColumn, dependentBase.FindProperty("PrincipalAlternateId")!, dependentBasebyteTableMapping); RelationalModel.CreateColumnMapping(principalIdColumn, dependentBase.FindProperty("PrincipalId")!, dependentBasebyteTableMapping); RelationalModel.CreateColumnMapping(enumDiscriminatorColumn, dependentBase.FindProperty("EnumDiscriminator")!, dependentBasebyteTableMapping); - RelationalModel.CreateColumnMapping(idColumn0, dependentBase.FindProperty("Id")!, dependentBasebyteTableMapping); + RelationalModel.CreateColumnMapping(idColumn1, dependentBase.FindProperty("Id")!, dependentBasebyteTableMapping); var dependentDerived = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+DependentDerived")!; - var defaultTableMappings1 = new List>(); - dependentDerived.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings1); + var defaultTableMappings2 = new List>(); + dependentDerived.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings2); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0 = new TableMappingBase(dependentDerived, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0, false); - defaultTableMappings1.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); + defaultTableMappings2.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)principalAlternateIdColumnBase, dependentDerived.FindProperty("PrincipalAlternateId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)principalIdColumnBase, dependentDerived.FindProperty("PrincipalId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)dataColumnBase, dependentDerived.FindProperty("Data")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)enumDiscriminatorColumnBase, dependentDerived.FindProperty("EnumDiscriminator")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase0, dependentDerived.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase1, dependentDerived.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); RelationalModel.CreateColumnMapping((ColumnBase)moneyColumnBase, dependentDerived.FindProperty("Money")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseDependentBasebyteMappingBase0); - var tableMappings1 = new List(); - dependentDerived.SetRuntimeAnnotation("Relational:TableMappings", tableMappings1); + var tableMappings2 = new List(); + dependentDerived.SetRuntimeAnnotation("Relational:TableMappings", tableMappings2); var dependentBasebyteTableMapping0 = new TableMapping(dependentDerived, dependentBasebyteTable, null) { IsSharedTablePrincipal = false, }; dependentBasebyteTable.AddTypeMapping(dependentBasebyteTableMapping0, false); - tableMappings1.Add(dependentBasebyteTableMapping0); + tableMappings2.Add(dependentBasebyteTableMapping0); RelationalModel.CreateColumnMapping(principalAlternateIdColumn, dependentDerived.FindProperty("PrincipalAlternateId")!, dependentBasebyteTableMapping0); RelationalModel.CreateColumnMapping(principalIdColumn, dependentDerived.FindProperty("PrincipalId")!, dependentBasebyteTableMapping0); RelationalModel.CreateColumnMapping(dataColumn, dependentDerived.FindProperty("Data")!, dependentBasebyteTableMapping0); RelationalModel.CreateColumnMapping(enumDiscriminatorColumn, dependentDerived.FindProperty("EnumDiscriminator")!, dependentBasebyteTableMapping0); - RelationalModel.CreateColumnMapping(idColumn0, dependentDerived.FindProperty("Id")!, dependentBasebyteTableMapping0); + RelationalModel.CreateColumnMapping(idColumn1, dependentDerived.FindProperty("Id")!, dependentBasebyteTableMapping0); RelationalModel.CreateColumnMapping(moneyColumn, dependentDerived.FindProperty("Money")!, dependentBasebyteTableMapping0); var pK_DependentBasebyte = new UniqueConstraint("PK_DependentBase", dependentBasebyteTable, new[] { principalIdColumn, principalAlternateIdColumn }); dependentBasebyteTable.PrimaryKey = pK_DependentBasebyte; @@ -247,8 +296,8 @@ private IRelationalModel CreateRelationalModel() var manyTypes = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+ManyTypes")!; - var defaultTableMappings2 = new List>(); - manyTypes.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings2); + var defaultTableMappings3 = new List>(); + manyTypes.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings3); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase = new TableBase("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+ManyTypes", null, relationalModel); var boolColumnBase = new ColumnBase("Bool", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.Columns.Add("Bool", boolColumnBase); @@ -436,8 +485,8 @@ private IRelationalModel CreateRelationalModel() microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.Columns.Add("IPAddressToBytesConverterProperty", iPAddressToBytesConverterPropertyColumnBase); var iPAddressToStringConverterPropertyColumnBase = new ColumnBase("IPAddressToStringConverterProperty", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.Columns.Add("IPAddressToStringConverterProperty", iPAddressToStringConverterPropertyColumnBase); - var idColumnBase1 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); - microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.Columns.Add("Id", idColumnBase1); + var idColumnBase2 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); + microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.Columns.Add("Id", idColumnBase2); var int16ColumnBase = new ColumnBase("Int16", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.Columns.Add("Int16", int16ColumnBase); var int16ArrayColumnBase = new ColumnBase("Int16Array", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); @@ -858,8 +907,8 @@ private IRelationalModel CreateRelationalModel() relationalModel.DefaultTables.Add("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+ManyTypes", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase = new TableMappingBase(manyTypes, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase, false); - defaultTableMappings2.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase1, manyTypes.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); + defaultTableMappings3.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase2, manyTypes.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)boolColumnBase, manyTypes.FindProperty("Bool")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)boolArrayColumnBase, manyTypes.FindProperty("BoolArray")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)boolReadOnlyCollectionColumnBase, manyTypes.FindProperty("BoolReadOnlyCollection")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); @@ -1101,12 +1150,12 @@ private IRelationalModel CreateRelationalModel() RelationalModel.CreateColumnMapping((ColumnBase)uriArrayColumnBase, manyTypes.FindProperty("UriArray")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)uriToStringConverterPropertyColumnBase, manyTypes.FindProperty("UriToStringConverterProperty")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBaseManyTypesMappingBase); - var tableMappings2 = new List(); - manyTypes.SetRuntimeAnnotation("Relational:TableMappings", tableMappings2); + var tableMappings3 = new List(); + manyTypes.SetRuntimeAnnotation("Relational:TableMappings", tableMappings3); var manyTypesTable = new Table("ManyTypes", null, relationalModel); - var idColumn1 = new Column("Id", "INTEGER", manyTypesTable); - manyTypesTable.Columns.Add("Id", idColumn1); - idColumn1.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn1); + var idColumn2 = new Column("Id", "INTEGER", manyTypesTable); + manyTypesTable.Columns.Add("Id", idColumn2); + idColumn2.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn2); var boolColumn = new Column("Bool", "INTEGER", manyTypesTable); manyTypesTable.Columns.Add("Bool", boolColumn); boolColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(boolColumn); @@ -1953,8 +2002,8 @@ private IRelationalModel CreateRelationalModel() relationalModel.Tables.Add(("ManyTypes", null), manyTypesTable); var manyTypesTableMapping = new TableMapping(manyTypes, manyTypesTable, null); manyTypesTable.AddTypeMapping(manyTypesTableMapping, false); - tableMappings2.Add(manyTypesTableMapping); - RelationalModel.CreateColumnMapping(idColumn1, manyTypes.FindProperty("Id")!, manyTypesTableMapping); + tableMappings3.Add(manyTypesTableMapping); + RelationalModel.CreateColumnMapping(idColumn2, manyTypes.FindProperty("Id")!, manyTypesTableMapping); RelationalModel.CreateColumnMapping(boolColumn, manyTypes.FindProperty("Bool")!, manyTypesTableMapping); RelationalModel.CreateColumnMapping(boolArrayColumn, manyTypes.FindProperty("BoolArray")!, manyTypesTableMapping); RelationalModel.CreateColumnMapping(boolReadOnlyCollectionColumn, manyTypes.FindProperty("BoolReadOnlyCollection")!, manyTypesTableMapping); @@ -2195,7 +2244,7 @@ private IRelationalModel CreateRelationalModel() RelationalModel.CreateColumnMapping(uriColumn, manyTypes.FindProperty("Uri")!, manyTypesTableMapping); RelationalModel.CreateColumnMapping(uriArrayColumn, manyTypes.FindProperty("UriArray")!, manyTypesTableMapping); RelationalModel.CreateColumnMapping(uriToStringConverterPropertyColumn, manyTypes.FindProperty("UriToStringConverterProperty")!, manyTypesTableMapping); - var pK_ManyTypes = new UniqueConstraint("PK_ManyTypes", manyTypesTable, new[] { idColumn1 }); + var pK_ManyTypes = new UniqueConstraint("PK_ManyTypes", manyTypesTable, new[] { idColumn2 }); manyTypesTable.PrimaryKey = pK_ManyTypes; pK_ManyTypes.SetRowKeyValueFactory(new SimpleRowKeyValueFactory(pK_ManyTypes)); var pK_ManyTypesKey = RelationalModel.GetKey(this, @@ -2207,8 +2256,8 @@ private IRelationalModel CreateRelationalModel() var principalBase = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase")!; - var defaultTableMappings3 = new List>(); - principalBase.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings3); + var defaultTableMappings4 = new List>(); + principalBase.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings4); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase = new TableBase("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", null, relationalModel); var alternateIdColumnBase = new ColumnBase("AlternateId", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.Columns.Add("AlternateId", alternateIdColumnBase); @@ -2225,8 +2274,8 @@ private IRelationalModel CreateRelationalModel() microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.Columns.Add("FlagsEnum1", flagsEnum1ColumnBase); var flagsEnum2ColumnBase = new ColumnBase("FlagsEnum2", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.Columns.Add("FlagsEnum2", flagsEnum2ColumnBase); - var idColumnBase2 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase); - microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.Columns.Add("Id", idColumnBase2); + var idColumnBase3 = new ColumnBase("Id", "INTEGER", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase); + microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.Columns.Add("Id", idColumnBase3); var manyOwnedColumnBase = new JsonColumnBase("ManyOwned", "TEXT", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase) { IsNullable = true @@ -2282,9 +2331,9 @@ private IRelationalModel CreateRelationalModel() relationalModel.DefaultTables.Add("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase = new TableMappingBase(principalBase, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase, true); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase, false); - defaultTableMappings3.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); + defaultTableMappings4.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)alternateIdColumnBase, principalBase.FindProperty("AlternateId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase2, principalBase.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase3, principalBase.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)discriminatorColumnBase, principalBase.FindProperty("Discriminator")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)enum1ColumnBase, principalBase.FindProperty("Enum1")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)enum2ColumnBase, principalBase.FindProperty("Enum2")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); @@ -2300,12 +2349,12 @@ private IRelationalModel CreateRelationalModel() RelationalModel.CreateColumnMapping((ColumnBase)valueTypeIListColumnBase, principalBase.FindProperty("ValueTypeIList")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)valueTypeListColumnBase, principalBase.FindProperty("ValueTypeList")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase); - var tableMappings3 = new List(); - principalBase.SetRuntimeAnnotation("Relational:TableMappings", tableMappings3); + var tableMappings4 = new List(); + principalBase.SetRuntimeAnnotation("Relational:TableMappings", tableMappings4); var principalBaseTable = new Table("PrincipalBase", null, relationalModel); - var idColumn2 = new Column("Id", "INTEGER", principalBaseTable); - principalBaseTable.Columns.Add("Id", idColumn2); - idColumn2.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn2); + var idColumn3 = new Column("Id", "INTEGER", principalBaseTable); + principalBaseTable.Columns.Add("Id", idColumn3); + idColumn3.Accessors = ColumnAccessorsFactory.CreateGeneric(idColumn3); var alternateIdColumn = new Column("AlternateId", "TEXT", principalBaseTable); principalBaseTable.Columns.Add("AlternateId", alternateIdColumn); alternateIdColumn.Accessors = ColumnAccessorsFactory.CreateGeneric(alternateIdColumn); @@ -2396,9 +2445,9 @@ private IRelationalModel CreateRelationalModel() IsSharedTablePrincipal = true, }; principalBaseTable.AddTypeMapping(principalBaseTableMapping, false); - tableMappings3.Add(principalBaseTableMapping); + tableMappings4.Add(principalBaseTableMapping); RelationalModel.CreateColumnMapping(alternateIdColumn, principalBase.FindProperty("AlternateId")!, principalBaseTableMapping); - RelationalModel.CreateColumnMapping(idColumn2, principalBase.FindProperty("Id")!, principalBaseTableMapping); + RelationalModel.CreateColumnMapping(idColumn3, principalBase.FindProperty("Id")!, principalBaseTableMapping); RelationalModel.CreateColumnMapping(discriminatorColumn, principalBase.FindProperty("Discriminator")!, principalBaseTableMapping); RelationalModel.CreateColumnMapping(enum1Column, principalBase.FindProperty("Enum1")!, principalBaseTableMapping); RelationalModel.CreateColumnMapping(enum2Column, principalBase.FindProperty("Enum2")!, principalBaseTableMapping); @@ -2416,20 +2465,20 @@ private IRelationalModel CreateRelationalModel() var ownedType = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase.Owned#OwnedType")!; - var defaultTableMappings4 = new List>(); - ownedType.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings4); + var defaultTableMappings5 = new List>(); + ownedType.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings5); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0 = new TableMappingBase(ownedType, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0, null); - defaultTableMappings4.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0); + defaultTableMappings5.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase0); - var tableMappings4 = new List(); - ownedType.SetRuntimeAnnotation("Relational:TableMappings", tableMappings4); + var tableMappings5 = new List(); + ownedType.SetRuntimeAnnotation("Relational:TableMappings", tableMappings5); var principalBaseTableMapping0 = new TableMapping(ownedType, principalBaseTable, null) { IsSharedTablePrincipal = false, }; principalBaseTable.AddTypeMapping(principalBaseTableMapping0, null); - tableMappings4.Add(principalBaseTableMapping0); + tableMappings5.Add(principalBaseTableMapping0); principalBaseTable.AddRowInternalForeignKey(ownedType, RelationalModel.GetForeignKey(this, "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase.Owned#OwnedType", new[] { "PrincipalBaseId", "PrincipalBaseAlternateId" }, @@ -2438,13 +2487,13 @@ private IRelationalModel CreateRelationalModel() var principalDerived = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>")!; - var defaultTableMappings5 = new List>(); - principalDerived.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings5); + var defaultTableMappings6 = new List>(); + principalDerived.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings6); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1 = new TableMappingBase(principalDerived, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1, false); - defaultTableMappings5.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); + defaultTableMappings6.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); RelationalModel.CreateColumnMapping((ColumnBase)alternateIdColumnBase, principalDerived.FindProperty("AlternateId")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); - RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase2, principalDerived.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); + RelationalModel.CreateColumnMapping((ColumnBase)idColumnBase3, principalDerived.FindProperty("Id")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); RelationalModel.CreateColumnMapping((ColumnBase)discriminatorColumnBase, principalDerived.FindProperty("Discriminator")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); RelationalModel.CreateColumnMapping((ColumnBase)enum1ColumnBase, principalDerived.FindProperty("Enum1")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); RelationalModel.CreateColumnMapping((ColumnBase)enum2ColumnBase, principalDerived.FindProperty("Enum2")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); @@ -2460,16 +2509,16 @@ private IRelationalModel CreateRelationalModel() RelationalModel.CreateColumnMapping((ColumnBase)valueTypeIListColumnBase, principalDerived.FindProperty("ValueTypeIList")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); RelationalModel.CreateColumnMapping((ColumnBase)valueTypeListColumnBase, principalDerived.FindProperty("ValueTypeList")!, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase1); - var tableMappings5 = new List(); - principalDerived.SetRuntimeAnnotation("Relational:TableMappings", tableMappings5); + var tableMappings6 = new List(); + principalDerived.SetRuntimeAnnotation("Relational:TableMappings", tableMappings6); var principalBaseTableMapping1 = new TableMapping(principalDerived, principalBaseTable, null) { IsSharedTablePrincipal = false, }; principalBaseTable.AddTypeMapping(principalBaseTableMapping1, false); - tableMappings5.Add(principalBaseTableMapping1); + tableMappings6.Add(principalBaseTableMapping1); RelationalModel.CreateColumnMapping(alternateIdColumn, principalDerived.FindProperty("AlternateId")!, principalBaseTableMapping1); - RelationalModel.CreateColumnMapping(idColumn2, principalDerived.FindProperty("Id")!, principalBaseTableMapping1); + RelationalModel.CreateColumnMapping(idColumn3, principalDerived.FindProperty("Id")!, principalBaseTableMapping1); RelationalModel.CreateColumnMapping(discriminatorColumn, principalDerived.FindProperty("Discriminator")!, principalBaseTableMapping1); RelationalModel.CreateColumnMapping(enum1Column, principalDerived.FindProperty("Enum1")!, principalBaseTableMapping1); RelationalModel.CreateColumnMapping(enum2Column, principalDerived.FindProperty("Enum2")!, principalBaseTableMapping1); @@ -2487,26 +2536,26 @@ private IRelationalModel CreateRelationalModel() var ownedType0 = FindEntityType("Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>.ManyOwned#OwnedType")!; - var defaultTableMappings6 = new List>(); - ownedType0.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings6); + var defaultTableMappings7 = new List>(); + ownedType0.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings7); var microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase2 = new TableMappingBase(ownedType0, microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase, null); microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseTableBase.AddTypeMapping(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase2, null); - defaultTableMappings6.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase2); + defaultTableMappings7.Add(microsoftEntityFrameworkCoreScaffoldingCompiledModelTestBasePrincipalBaseMappingBase2); - var tableMappings6 = new List(); - ownedType0.SetRuntimeAnnotation("Relational:TableMappings", tableMappings6); + var tableMappings7 = new List(); + ownedType0.SetRuntimeAnnotation("Relational:TableMappings", tableMappings7); var principalBaseTableMapping2 = new TableMapping(ownedType0, principalBaseTable, null) { IsSharedTablePrincipal = false, }; principalBaseTable.AddTypeMapping(principalBaseTableMapping2, null); - tableMappings6.Add(principalBaseTableMapping2); + tableMappings7.Add(principalBaseTableMapping2); principalBaseTable.AddRowInternalForeignKey(ownedType0, RelationalModel.GetForeignKey(this, "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>.ManyOwned#OwnedType", new[] { "PrincipalDerivedId", "PrincipalDerivedAlternateId" }, "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalDerived>", new[] { "Id", "AlternateId" })); - var aK_PrincipalBase_Id = new UniqueConstraint("AK_PrincipalBase_Id", principalBaseTable, new[] { idColumn2 }); + var aK_PrincipalBase_Id = new UniqueConstraint("AK_PrincipalBase_Id", principalBaseTable, new[] { idColumn3 }); aK_PrincipalBase_Id.SetRowKeyValueFactory(new SimpleRowKeyValueFactory(aK_PrincipalBase_Id)); var aK_PrincipalBase_IdKey = RelationalModel.GetKey(this, "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", @@ -2514,7 +2563,7 @@ private IRelationalModel CreateRelationalModel() aK_PrincipalBase_Id.MappedKeys.Add(aK_PrincipalBase_IdKey); RelationalModel.GetOrCreateUniqueConstraints(aK_PrincipalBase_IdKey).Add(aK_PrincipalBase_Id); principalBaseTable.UniqueConstraints.Add("AK_PrincipalBase_Id", aK_PrincipalBase_Id); - var pK = new UniqueConstraint("PK", principalBaseTable, new[] { idColumn2, alternateIdColumn }); + var pK = new UniqueConstraint("PK", principalBaseTable, new[] { idColumn3, alternateIdColumn }); principalBaseTable.PrimaryKey = pK; pK.SetRowKeyValueFactory(new CompositeRowKeyValueFactory(pK)); var pKKey = RelationalModel.GetKey(this, @@ -2524,7 +2573,7 @@ private IRelationalModel CreateRelationalModel() RelationalModel.GetOrCreateUniqueConstraints(pKKey).Add(pK); principalBaseTable.UniqueConstraints.Add("PK", pK); var iX_PrincipalBase_AlternateId_Id = new TableIndex( - "IX_PrincipalBase_AlternateId_Id", principalBaseTable, new[] { alternateIdColumn, idColumn2 }, false); + "IX_PrincipalBase_AlternateId_Id", principalBaseTable, new[] { alternateIdColumn, idColumn3 }, false); iX_PrincipalBase_AlternateId_Id.SetRowIndexValueFactory(new CompositeRowIndexValueFactory(iX_PrincipalBase_AlternateId_Id)); var iX_PrincipalBase_AlternateId_IdIx = RelationalModel.GetIndex(this, "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelTestBase+PrincipalBase", @@ -2535,8 +2584,8 @@ private IRelationalModel CreateRelationalModel() var principalBasePrincipalDerivedDependentBasebyte = FindEntityType("PrincipalBasePrincipalDerived>")!; - var defaultTableMappings7 = new List>(); - principalBasePrincipalDerivedDependentBasebyte.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings7); + var defaultTableMappings8 = new List>(); + principalBasePrincipalDerivedDependentBasebyte.SetRuntimeAnnotation("Relational:DefaultMappings", defaultTableMappings8); var principalBasePrincipalDerivedDependentBasebyteTableBase = new TableBase("PrincipalBasePrincipalDerived>", null, relationalModel); var derivedsAlternateIdColumnBase = new ColumnBase("DerivedsAlternateId", "TEXT", principalBasePrincipalDerivedDependentBasebyteTableBase); principalBasePrincipalDerivedDependentBasebyteTableBase.Columns.Add("DerivedsAlternateId", derivedsAlternateIdColumnBase); @@ -2554,15 +2603,15 @@ private IRelationalModel CreateRelationalModel() relationalModel.DefaultTables.Add("PrincipalBasePrincipalDerived>", principalBasePrincipalDerivedDependentBasebyteTableBase); var principalBasePrincipalDerivedDependentBasebyteMappingBase = new TableMappingBase(principalBasePrincipalDerivedDependentBasebyte, principalBasePrincipalDerivedDependentBasebyteTableBase, null); principalBasePrincipalDerivedDependentBasebyteTableBase.AddTypeMapping(principalBasePrincipalDerivedDependentBasebyteMappingBase, false); - defaultTableMappings7.Add(principalBasePrincipalDerivedDependentBasebyteMappingBase); + defaultTableMappings8.Add(principalBasePrincipalDerivedDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)derivedsAlternateIdColumnBase, principalBasePrincipalDerivedDependentBasebyte.FindProperty("DerivedsAlternateId")!, principalBasePrincipalDerivedDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)derivedsIdColumnBase, principalBasePrincipalDerivedDependentBasebyte.FindProperty("DerivedsId")!, principalBasePrincipalDerivedDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)principalsAlternateIdColumnBase, principalBasePrincipalDerivedDependentBasebyte.FindProperty("PrincipalsAlternateId")!, principalBasePrincipalDerivedDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)principalsIdColumnBase, principalBasePrincipalDerivedDependentBasebyte.FindProperty("PrincipalsId")!, principalBasePrincipalDerivedDependentBasebyteMappingBase); RelationalModel.CreateColumnMapping((ColumnBase)rowidColumnBase, principalBasePrincipalDerivedDependentBasebyte.FindProperty("rowid")!, principalBasePrincipalDerivedDependentBasebyteMappingBase); - var tableMappings7 = new List(); - principalBasePrincipalDerivedDependentBasebyte.SetRuntimeAnnotation("Relational:TableMappings", tableMappings7); + var tableMappings8 = new List(); + principalBasePrincipalDerivedDependentBasebyte.SetRuntimeAnnotation("Relational:TableMappings", tableMappings8); var principalBasePrincipalDerivedDependentBasebyteTable = new Table("PrincipalBasePrincipalDerived>", null, relationalModel); var derivedsIdColumn = new Column("DerivedsId", "INTEGER", principalBasePrincipalDerivedDependentBasebyteTable); principalBasePrincipalDerivedDependentBasebyteTable.Columns.Add("DerivedsId", derivedsIdColumn); @@ -2585,7 +2634,7 @@ private IRelationalModel CreateRelationalModel() relationalModel.Tables.Add(("PrincipalBasePrincipalDerived>", null), principalBasePrincipalDerivedDependentBasebyteTable); var principalBasePrincipalDerivedDependentBasebyteTableMapping = new TableMapping(principalBasePrincipalDerivedDependentBasebyte, principalBasePrincipalDerivedDependentBasebyteTable, null); principalBasePrincipalDerivedDependentBasebyteTable.AddTypeMapping(principalBasePrincipalDerivedDependentBasebyteTableMapping, false); - tableMappings7.Add(principalBasePrincipalDerivedDependentBasebyteTableMapping); + tableMappings8.Add(principalBasePrincipalDerivedDependentBasebyteTableMapping); RelationalModel.CreateColumnMapping(derivedsAlternateIdColumn, principalBasePrincipalDerivedDependentBasebyte.FindProperty("DerivedsAlternateId")!, principalBasePrincipalDerivedDependentBasebyteTableMapping); RelationalModel.CreateColumnMapping(derivedsIdColumn, principalBasePrincipalDerivedDependentBasebyte.FindProperty("DerivedsId")!, principalBasePrincipalDerivedDependentBasebyteTableMapping); RelationalModel.CreateColumnMapping(principalsAlternateIdColumn, principalBasePrincipalDerivedDependentBasebyte.FindProperty("PrincipalsAlternateId")!, principalBasePrincipalDerivedDependentBasebyteTableMapping); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/AutoIncrementEntityEntityType.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/AutoIncrementEntityEntityType.cs new file mode 100644 index 00000000000..b2c8daee62c --- /dev/null +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/AutoIncrementEntityEntityType.cs @@ -0,0 +1,62 @@ +// +using System; +using System.Reflection; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Scaffolding; + +#pragma warning disable 219, 612, 618 +#nullable disable + +namespace TestNamespace +{ + [EntityFrameworkInternal] + public partial class AutoIncrementEntityEntityType + { + public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null) + { + var runtimeEntityType = model.AddEntityType( + "Microsoft.EntityFrameworkCore.Scaffolding.CompiledModelSqliteTest+AutoIncrementEntity", + typeof(CompiledModelSqliteTest.AutoIncrementEntity), + baseEntityType, + propertyCount: 2, + keyCount: 1); + + var id = runtimeEntityType.AddProperty( + "Id", + typeof(int), + propertyInfo: typeof(CompiledModelSqliteTest.AutoIncrementEntity).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelSqliteTest.AutoIncrementEntity).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + valueGenerated: ValueGenerated.OnAdd, + afterSaveBehavior: PropertySaveBehavior.Throw, + sentinel: 0); + + var name = runtimeEntityType.AddProperty( + "Name", + typeof(string), + propertyInfo: typeof(CompiledModelSqliteTest.AutoIncrementEntity).GetProperty("Name", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly), + fieldInfo: typeof(CompiledModelSqliteTest.AutoIncrementEntity).GetField("k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly), + nullable: true); + + var key = runtimeEntityType.AddKey( + new[] { id }); + runtimeEntityType.SetPrimaryKey(key); + + return runtimeEntityType; + } + + public static void CreateAnnotations(RuntimeEntityType runtimeEntityType) + { + runtimeEntityType.AddAnnotation("Relational:FunctionName", null); + runtimeEntityType.AddAnnotation("Relational:Schema", null); + runtimeEntityType.AddAnnotation("Relational:SqlQuery", null); + runtimeEntityType.AddAnnotation("Relational:TableName", "AutoIncrementEntity"); + runtimeEntityType.AddAnnotation("Relational:ViewName", null); + runtimeEntityType.AddAnnotation("Relational:ViewSchema", null); + + Customize(runtimeEntityType); + } + + static partial void Customize(RuntimeEntityType runtimeEntityType); + } +} diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs index 548895ceeb8..1c658a59982 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/Baselines/No_NativeAOT/DbContextModelBuilder.cs @@ -11,12 +11,13 @@ namespace TestNamespace public partial class DbContextModel { private DbContextModel() - : base(skipDetectChanges: false, modelId: new Guid("00000000-0000-0000-0000-000000000000"), entityTypeCount: 9) + : base(skipDetectChanges: false, modelId: new Guid("00000000-0000-0000-0000-000000000000"), entityTypeCount: 10) { } partial void Initialize() { + var autoIncrementEntity = AutoIncrementEntityEntityType.Create(this); var data = DataEntityType.Create(this); var dependentBase = DependentBaseEntityType.Create(this); var manyTypes = ManyTypesEntityType.Create(this); @@ -39,6 +40,7 @@ partial void Initialize() PrincipalBaseEntityType.CreateSkipNavigation1(principalBase, principalDerived, principalBasePrincipalDerivedDependentBasebyte); PrincipalDerivedEntityType.CreateSkipNavigation1(principalDerived, principalBase, principalBasePrincipalDerivedDependentBasebyte); + AutoIncrementEntityEntityType.CreateAnnotations(autoIncrementEntity); DataEntityType.CreateAnnotations(data); DependentBaseEntityType.CreateAnnotations(dependentBase); ManyTypesEntityType.CreateAnnotations(manyTypes); diff --git a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/CompiledModelSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/CompiledModelSqliteTest.cs index fe8f4a4772f..5b405ec9197 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Scaffolding/CompiledModelSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Scaffolding/CompiledModelSqliteTest.cs @@ -27,6 +27,13 @@ protected override void BuildBigModel(ModelBuilder modelBuilder, bool jsonColumn .HasSrid(1101); }); + modelBuilder.Entity(eb => + { + eb.Property("Id"); + eb.HasKey("Id"); + eb.Property("Name"); + }); + modelBuilder.Entity(eb => { eb.Property("Point") @@ -76,6 +83,15 @@ protected override void AssertBigModel(IModel model, bool jsonColumns) Assert.IsType>(pointProperty.GetKeyValueComparer()); Assert.IsType>(pointProperty.GetProviderValueComparer()); Assert.Null(pointProperty[CoreAnnotationNames.PropertyAccessMode]); + + var autoIncrementEntity = model.FindEntityType(typeof(AutoIncrementEntity))!; + var idProperty = autoIncrementEntity.FindProperty("Id")!; + Assert.Equal(typeof(int), idProperty.ClrType); + Assert.False(idProperty.IsNullable); + Assert.Equal(ValueGenerated.OnAdd, idProperty.ValueGenerated); + Assert.Equal("Id", idProperty.GetColumnName()); + Assert.Equal("INTEGER", idProperty.GetColumnType()); + Assert.Equal(SqliteValueGenerationStrategy.Autoincrement, idProperty.GetValueGenerationStrategy()); } //Sprocs not supported @@ -117,4 +133,10 @@ protected override BuildSource AddReferences(BuildSource build, [CallerFilePath] build.References.Add(BuildReference.ByName("NetTopologySuite")); return build; } + + public class AutoIncrementEntity + { + public int Id { get; set; } + public string? Name { get; set; } + } } diff --git a/test/EFCore.Sqlite.Tests/Diagnostics/SqliteEventIdTest.cs b/test/EFCore.Sqlite.Tests/Diagnostics/SqliteEventIdTest.cs index db94c79db85..bac970c7d90 100644 --- a/test/EFCore.Sqlite.Tests/Diagnostics/SqliteEventIdTest.cs +++ b/test/EFCore.Sqlite.Tests/Diagnostics/SqliteEventIdTest.cs @@ -22,6 +22,7 @@ public void Every_eventId_has_a_logger_method_and_logs_when_level_enabled() { typeof(string), () => "Fake" }, { typeof(IEntityType), () => entityType }, { typeof(IKey), () => new Key([property], ConfigurationSource.Convention) }, + { typeof(IReadOnlyProperty), () => property }, { typeof(IReadOnlySequence), () => new FakeSequence() }, { typeof(Type), () => typeof(object) } }; diff --git a/test/EFCore.Sqlite.Tests/Extensions/SqliteMetadataExtensionsTest.cs b/test/EFCore.Sqlite.Tests/Extensions/SqliteMetadataExtensionsTest.cs index 3b664c18c79..94bfa945f2c 100644 --- a/test/EFCore.Sqlite.Tests/Extensions/SqliteMetadataExtensionsTest.cs +++ b/test/EFCore.Sqlite.Tests/Extensions/SqliteMetadataExtensionsTest.cs @@ -26,9 +26,195 @@ public void Can_get_and_set_srid() Assert.Null(property.GetSrid()); } + [ConditionalFact] + public void Can_get_and_set_value_generation_strategy() + { + var modelBuilder = new ModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.Id) + .Metadata; + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + + property.SetValueGenerationStrategy(SqliteValueGenerationStrategy.Autoincrement); + + Assert.Equal(SqliteValueGenerationStrategy.Autoincrement, property.GetValueGenerationStrategy()); + + property.SetValueGenerationStrategy(null); + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void Can_set_value_generation_strategy_on_mutable_property() + { + var modelBuilder = new ModelBuilder(); + + var property = (IMutableProperty)modelBuilder + .Entity() + .Property(e => e.Id) + .Metadata; + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + + ((IMutableProperty)property).SetValueGenerationStrategy(SqliteValueGenerationStrategy.Autoincrement); + + Assert.Equal(SqliteValueGenerationStrategy.Autoincrement, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void Default_value_generation_strategy_for_integer_primary_key() + { + var modelBuilder = new ModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.Id) + .Metadata; + + // Without conventions, the default should be None + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_for_non_primary_key() + { + var modelBuilder = new ModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.OtherId) + .Metadata; + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_for_non_integer_primary_key() + { + var modelBuilder = new ModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.Id) + .Metadata; + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_for_composite_primary_key() + { + var modelBuilder = new ModelBuilder(); + + modelBuilder + .Entity(b => + { + b.HasKey(e => new { e.Id1, e.Id2 }); + }); + + var property1 = modelBuilder.Entity().Property(e => e.Id1).Metadata; + var property2 = modelBuilder.Entity().Property(e => e.Id2).Metadata; + + Assert.Equal(SqliteValueGenerationStrategy.None, property1.GetValueGenerationStrategy()); + Assert.Equal(SqliteValueGenerationStrategy.None, property2.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_when_default_value_set() + { + var modelBuilder = new ModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.Id) + .HasDefaultValue(42) + .Metadata; + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_when_default_value_sql_set() + { + var modelBuilder = new ModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.Id) + .HasDefaultValueSql("1") + .Metadata; + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_when_computed_column_sql_set() + { + var modelBuilder = new ModelBuilder(); + + var property = modelBuilder + .Entity() + .Property(e => e.Id) + .HasComputedColumnSql("1") + .Metadata; + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + + [ConditionalFact] + public void No_autoincrement_when_property_is_foreign_key() + { + var modelBuilder = new ModelBuilder(); + + modelBuilder.Entity(b => + { + b.HasKey(e => e.Id); + b.Property(e => e.CustomerId); + b.HasOne() + .WithMany() + .HasForeignKey(e => e.CustomerId); + }); + + var property = modelBuilder.Entity().Property(e => e.CustomerId).Metadata; + + Assert.Equal(SqliteValueGenerationStrategy.None, property.GetValueGenerationStrategy()); + } + private class Customer { public int Id { get; set; } + public int OtherId { get; set; } + public string? Name { get; set; } + public string? Geometry { get; set; } + } + + private class CustomerWithStringKey + { + public string Id { get; set; } = null!; + public string? Name { get; set; } + } + + private class CustomerWithCompositeKey + { + public int Id1 { get; set; } + public int Id2 { get; set; } + public string? Name { get; set; } + } + + private class Order + { + public int Id { get; set; } + public int CustomerId { get; set; } + } + + private class CustomerNoPK + { + public int Id { get; set; } + public int OtherId { get; set; } + public string? Name { get; set; } public string? Geometry { get; set; } } } diff --git a/test/EFCore.Sqlite.Tests/Infrastructure/SqliteModelValidatorTest.cs b/test/EFCore.Sqlite.Tests/Infrastructure/SqliteModelValidatorTest.cs index f676f77dbed..1ae2e320eda 100644 --- a/test/EFCore.Sqlite.Tests/Infrastructure/SqliteModelValidatorTest.cs +++ b/test/EFCore.Sqlite.Tests/Infrastructure/SqliteModelValidatorTest.cs @@ -150,6 +150,36 @@ public override void Detects_unmapped_concurrency_token() Assert.Equal(SqliteStrings.StoredProceduresNotSupported(nameof(Animal)), exception.Message); } + [ConditionalFact] + public void Detects_conflicting_autoincrement_and_default_value_sql() + { + var modelBuilder = CreateConventionModelBuilder(); + modelBuilder.Entity() + .Property(e => e.Id) + .UseAutoincrement() + .HasDefaultValueSql("42"); + + VerifyWarning( + SqliteResources.LogConflictingValueGenerationStrategies( + new TestLogger()).GenerateMessage("Autoincrement", "DefaultValueSql", "Id", nameof(Person)), + modelBuilder); + } + + [ConditionalFact] + public void Detects_conflicting_autoincrement_and_computed_column() + { + var modelBuilder = CreateConventionModelBuilder(); + modelBuilder.Entity() + .Property(e => e.Id) + .UseAutoincrement() + .HasComputedColumnSql("42"); + + VerifyWarning( + SqliteResources.LogConflictingValueGenerationStrategies( + new TestLogger()).GenerateMessage("Autoincrement", "ComputedColumnSql", "Id", nameof(Person)), + modelBuilder); + } + public override void Store_generated_in_composite_key() { var modelBuilder = CreateConventionModelBuilder(); diff --git a/test/EFCore.Sqlite.Tests/Migrations/SqliteModelDifferTest.cs b/test/EFCore.Sqlite.Tests/Migrations/SqliteModelDifferTest.cs new file mode 100644 index 00000000000..f49c2b916f5 --- /dev/null +++ b/test/EFCore.Sqlite.Tests/Migrations/SqliteModelDifferTest.cs @@ -0,0 +1,145 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.EntityFrameworkCore.Migrations.Internal; +using Microsoft.EntityFrameworkCore.Sqlite.Metadata.Internal; + +// ReSharper disable InconsistentNaming +namespace Microsoft.EntityFrameworkCore.Migrations; + +public class SqliteModelDifferTest : MigrationsModelDifferTestBase +{ + [ConditionalFact] + public void Add_property_with_autoincrement_strategy() + => Execute( + _ => { }, + target => target.Entity( + "Person", + x => + { + x.Property("Id"); + x.HasKey("Id"); + x.Property("Id").UseAutoincrement(); + }), + upOps => + { + Assert.Equal(1, upOps.Count); + + var createTableOperation = Assert.IsType(upOps[0]); + var idColumn = createTableOperation.Columns.Single(c => c.Name == "Id"); + Assert.Equal(true, idColumn[SqliteAnnotationNames.Autoincrement]); + }); + + [ConditionalFact] + public void Alter_property_add_autoincrement_strategy() + => Execute( + common => common.Entity( + "Person", + x => + { + x.Property("Id").ValueGeneratedNever(); + x.HasKey("Id"); + }), + source => { }, + target => target.Entity("Person").Property("Id").ValueGeneratedOnAdd().UseAutoincrement(), + upOps => + { + Assert.Equal(1, upOps.Count); + + var alterColumnOperation = Assert.IsType(upOps[0]); + Assert.Equal(true, alterColumnOperation[SqliteAnnotationNames.Autoincrement]); + Assert.Null(alterColumnOperation.OldColumn[SqliteAnnotationNames.Autoincrement]); + }); + + [ConditionalFact] + public void Alter_property_remove_autoincrement_strategy() + => Execute( + common => common.Entity( + "Person", + x => + { + x.Property("Id"); + x.HasKey("Id"); + }), + source => { }, + target => target.Entity("Person").Property("Id").ValueGeneratedNever(), + upOps => + { + Assert.Equal(1, upOps.Count); + + var alterColumnOperation = Assert.IsType(upOps[0]); + Assert.Null(alterColumnOperation[SqliteAnnotationNames.Autoincrement]); + Assert.Equal(true, alterColumnOperation.OldColumn[SqliteAnnotationNames.Autoincrement]); + }); + + [ConditionalFact] + public void Autoincrement_with_value_converter_generates_consistent_migrations() + => Execute( + common => common.Entity( + x => + { + x.Property(e => e.Id).HasConversion( + v => v.Value, + v => new ProductId(v)); + x.HasKey(e => e.Id); + }), + source => { }, + target => target.Entity().Property(e => e.Id).UseAutoincrement(), + upOps => + { + Assert.Equal(1, upOps.Count); + + var alterColumnOperation = Assert.IsType(upOps[0]); + Assert.Equal(true, alterColumnOperation[SqliteAnnotationNames.Autoincrement]); + Assert.Null(alterColumnOperation.OldColumn[SqliteAnnotationNames.Autoincrement]); + }); + + [ConditionalFact] + public void No_repeated_alter_column_for_autoincrement_with_converter() + => Execute( + common => common.Entity( + x => + { + x.Property(e => e.Id).HasConversion( + v => v.Value, + v => new ProductId(v)); + x.HasKey(e => e.Id); + x.Property(e => e.Id).UseAutoincrement(); + }), + source => { }, + target => { }, + Assert.Empty); + + [ConditionalFact] + public void Noop_when_changing_to_autoincrement_property_with_converter() + => Execute( + source => source.Entity( + "ProductWithConverter", + x => + { + x.Property("Id"); + x.HasKey("Id"); + }), + target => target.Entity( + x => + { + x.Property(e => e.Id).HasConversion( + v => v.Value, + v => new ProductId(v)) + .UseAutoincrement(); + x.HasKey(e => e.Id); + x.Ignore(e => e.Name); + }), + Assert.Empty); + + protected override TestHelpers TestHelpers => SqliteTestHelpers.Instance; + + // Test entities + public record struct ProductId(int Value); + + public class ProductWithConverter + { + public ProductId Id { get; set; } + public required string Name { get; set; } + } +}