/// <summary> /// 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. /// </summary> protected virtual KeyBuilder VisitPrimaryKey([NotNull] EntityTypeBuilder builder, [NotNull] DatabaseTable table) { Check.NotNull(builder, nameof(builder)); Check.NotNull(table, nameof(table)); var primaryKey = table.PrimaryKey; var unmappedColumns = primaryKey.Columns .Where(c => _unmappedColumns.Contains(c)) .Select(c => c.Name) .ToList(); if (unmappedColumns.Count > 0) { _reporter.WriteWarning( DesignStrings.PrimaryKeyErrorPropertyNotFound( table.DisplayName(), string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator, unmappedColumns))); return(null); } var keyBuilder = builder.HasKey(primaryKey.Columns.Select(GetPropertyName).ToArray()); if (primaryKey.Columns.Count == 1 && primaryKey.Columns[0].ValueGenerated == null && primaryKey.Columns[0].DefaultValueSql == null) { var property = builder.Metadata.FindProperty(GetPropertyName(primaryKey.Columns[0]))?.AsProperty(); if (property != null) { var conventionalValueGenerated = ValueGenerationConvention.GetValueGenerated(property); if (conventionalValueGenerated == ValueGenerated.OnAdd) { property.ValueGenerated = ValueGenerated.Never; } } } if (!string.IsNullOrEmpty(primaryKey.Name) && primaryKey.Name != keyBuilder.Metadata.GetDefaultName()) { keyBuilder.HasName(primaryKey.Name); } keyBuilder.Metadata.AddAnnotations(primaryKey.GetAnnotations()); return(keyBuilder); }
private static InternalModelBuilder CreateInternalModelBuilder() { var conventions = new ConventionSet(); var dependencies = CreateDependencies(); conventions.EntityTypeAddedConventions.Add(new PropertyDiscoveryConvention(dependencies)); conventions.EntityTypeAddedConventions.Add(new KeyDiscoveryConvention(dependencies)); var keyConvention = new ValueGenerationConvention(dependencies); conventions.ForeignKeyAddedConventions.Add(keyConvention); conventions.ForeignKeyRemovedConventions.Add(keyConvention); conventions.EntityTypePrimaryKeyChangedConventions.Add(keyConvention); return(new InternalModelBuilder(new Model(conventions))); }
private static InternalModelBuilder CreateInternalModelBuilder() { var serviceProvider = InMemoryTestHelpers.Instance.CreateContextServices(); var conventionSet = new ConventionSet(); var dependencies = serviceProvider.GetRequiredService <ProviderConventionSetBuilderDependencies>(); // Use public API to add conventions, issue #214 conventionSet.EntityTypeAddedConventions.Add(new PropertyDiscoveryConvention(dependencies)); conventionSet.EntityTypeAddedConventions.Add(new KeyDiscoveryConvention(dependencies)); var keyConvention = new ValueGenerationConvention(dependencies); conventionSet.ForeignKeyAddedConventions.Add(keyConvention); conventionSet.ForeignKeyRemovedConventions.Add(keyConvention); conventionSet.EntityTypePrimaryKeyChangedConventions.Add(keyConvention); return(new Model(conventionSet, serviceProvider.GetRequiredService <ModelDependencies>()).Builder); }
/// <summary> /// Builds and returns the convention set for the current database provider. /// </summary> /// <returns>The convention set for the current database provider.</returns> public virtual ConventionSet CreateConventionSet() { var conventionSet = new ConventionSet(); var propertyDiscoveryConvention = new PropertyDiscoveryConvention(Dependencies); var keyDiscoveryConvention = new KeyDiscoveryConvention(Dependencies); var inversePropertyAttributeConvention = new InversePropertyAttributeConvention(Dependencies); var foreignKeyAttributeConvention = new ForeignKeyAttributeConvention(Dependencies); var relationshipDiscoveryConvention = new RelationshipDiscoveryConvention(Dependencies); var servicePropertyDiscoveryConvention = new ServicePropertyDiscoveryConvention(Dependencies); var indexAttributeConvention = new IndexAttributeConvention(Dependencies); var baseTypeDiscoveryConvention = new BaseTypeDiscoveryConvention(Dependencies); conventionSet.EntityTypeAddedConventions.Add(new NotMappedEntityTypeAttributeConvention(Dependencies)); conventionSet.EntityTypeAddedConventions.Add(new OwnedEntityTypeAttributeConvention(Dependencies)); conventionSet.EntityTypeAddedConventions.Add(new KeylessEntityTypeAttributeConvention(Dependencies)); conventionSet.EntityTypeAddedConventions.Add(new EntityTypeConfigurationEntityTypeAttributeConvention(Dependencies)); conventionSet.EntityTypeAddedConventions.Add(new NotMappedMemberAttributeConvention(Dependencies)); conventionSet.EntityTypeAddedConventions.Add(baseTypeDiscoveryConvention); conventionSet.EntityTypeAddedConventions.Add(propertyDiscoveryConvention); conventionSet.EntityTypeAddedConventions.Add(servicePropertyDiscoveryConvention); conventionSet.EntityTypeAddedConventions.Add(keyDiscoveryConvention); conventionSet.EntityTypeAddedConventions.Add(indexAttributeConvention); conventionSet.EntityTypeAddedConventions.Add(inversePropertyAttributeConvention); conventionSet.EntityTypeAddedConventions.Add(foreignKeyAttributeConvention); conventionSet.EntityTypeAddedConventions.Add(relationshipDiscoveryConvention); conventionSet.EntityTypeIgnoredConventions.Add(relationshipDiscoveryConvention); var discriminatorConvention = new DiscriminatorConvention(Dependencies); conventionSet.EntityTypeRemovedConventions.Add(inversePropertyAttributeConvention); conventionSet.EntityTypeRemovedConventions.Add(discriminatorConvention); var foreignKeyIndexConvention = new ForeignKeyIndexConvention(Dependencies); var valueGeneratorConvention = new ValueGenerationConvention(Dependencies); conventionSet.EntityTypeBaseTypeChangedConventions.Add(propertyDiscoveryConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(servicePropertyDiscoveryConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(keyDiscoveryConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(indexAttributeConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(inversePropertyAttributeConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(relationshipDiscoveryConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(foreignKeyIndexConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(valueGeneratorConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(discriminatorConvention); var foreignKeyPropertyDiscoveryConvention = new ForeignKeyPropertyDiscoveryConvention(Dependencies); conventionSet.EntityTypeMemberIgnoredConventions.Add(inversePropertyAttributeConvention); conventionSet.EntityTypeMemberIgnoredConventions.Add(relationshipDiscoveryConvention); conventionSet.EntityTypeMemberIgnoredConventions.Add(keyDiscoveryConvention); conventionSet.EntityTypeMemberIgnoredConventions.Add(foreignKeyPropertyDiscoveryConvention); var keyAttributeConvention = new KeyAttributeConvention(Dependencies); var backingFieldConvention = new BackingFieldConvention(Dependencies); var concurrencyCheckAttributeConvention = new ConcurrencyCheckAttributeConvention(Dependencies); var databaseGeneratedAttributeConvention = new DatabaseGeneratedAttributeConvention(Dependencies); var requiredPropertyAttributeConvention = new RequiredPropertyAttributeConvention(Dependencies); var nonNullableReferencePropertyConvention = new NonNullableReferencePropertyConvention(Dependencies); var maxLengthAttributeConvention = new MaxLengthAttributeConvention(Dependencies); var stringLengthAttributeConvention = new StringLengthAttributeConvention(Dependencies); var timestampAttributeConvention = new TimestampAttributeConvention(Dependencies); var backingFieldAttributeConvention = new BackingFieldAttributeConvention(Dependencies); var unicodeAttributeConvention = new UnicodeAttributeConvention(Dependencies); var precisionAttributeConvention = new PrecisionAttributeConvention(Dependencies); conventionSet.PropertyAddedConventions.Add(backingFieldAttributeConvention); conventionSet.PropertyAddedConventions.Add(backingFieldConvention); conventionSet.PropertyAddedConventions.Add(concurrencyCheckAttributeConvention); conventionSet.PropertyAddedConventions.Add(databaseGeneratedAttributeConvention); conventionSet.PropertyAddedConventions.Add(requiredPropertyAttributeConvention); conventionSet.PropertyAddedConventions.Add(nonNullableReferencePropertyConvention); conventionSet.PropertyAddedConventions.Add(maxLengthAttributeConvention); conventionSet.PropertyAddedConventions.Add(stringLengthAttributeConvention); conventionSet.PropertyAddedConventions.Add(timestampAttributeConvention); conventionSet.PropertyAddedConventions.Add(keyAttributeConvention); conventionSet.PropertyAddedConventions.Add(keyDiscoveryConvention); conventionSet.PropertyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.PropertyAddedConventions.Add(unicodeAttributeConvention); conventionSet.PropertyAddedConventions.Add(precisionAttributeConvention); conventionSet.EntityTypePrimaryKeyChangedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.EntityTypePrimaryKeyChangedConventions.Add(valueGeneratorConvention); conventionSet.KeyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.KeyAddedConventions.Add(foreignKeyIndexConvention); conventionSet.KeyRemovedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.KeyRemovedConventions.Add(foreignKeyIndexConvention); conventionSet.KeyRemovedConventions.Add(keyDiscoveryConvention); var cascadeDeleteConvention = new CascadeDeleteConvention(Dependencies); conventionSet.ForeignKeyAddedConventions.Add(foreignKeyAttributeConvention); conventionSet.ForeignKeyAddedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.ForeignKeyAddedConventions.Add(keyDiscoveryConvention); conventionSet.ForeignKeyAddedConventions.Add(valueGeneratorConvention); conventionSet.ForeignKeyAddedConventions.Add(cascadeDeleteConvention); conventionSet.ForeignKeyAddedConventions.Add(foreignKeyIndexConvention); conventionSet.ForeignKeyRemovedConventions.Add(baseTypeDiscoveryConvention); conventionSet.ForeignKeyRemovedConventions.Add(relationshipDiscoveryConvention); conventionSet.ForeignKeyRemovedConventions.Add(keyDiscoveryConvention); conventionSet.ForeignKeyRemovedConventions.Add(valueGeneratorConvention); conventionSet.ForeignKeyRemovedConventions.Add(foreignKeyIndexConvention); conventionSet.ForeignKeyPropertiesChangedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.ForeignKeyPropertiesChangedConventions.Add(keyDiscoveryConvention); conventionSet.ForeignKeyPropertiesChangedConventions.Add(valueGeneratorConvention); conventionSet.ForeignKeyPropertiesChangedConventions.Add(foreignKeyIndexConvention); conventionSet.ForeignKeyUniquenessChangedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.ForeignKeyUniquenessChangedConventions.Add(keyDiscoveryConvention); conventionSet.ForeignKeyUniquenessChangedConventions.Add(foreignKeyIndexConvention); conventionSet.ForeignKeyRequirednessChangedConventions.Add(cascadeDeleteConvention); conventionSet.ForeignKeyRequirednessChangedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.ForeignKeyOwnershipChangedConventions.Add(new NavigationEagerLoadingConvention(Dependencies)); conventionSet.ForeignKeyOwnershipChangedConventions.Add(relationshipDiscoveryConvention); conventionSet.ForeignKeyOwnershipChangedConventions.Add(keyDiscoveryConvention); conventionSet.ForeignKeyOwnershipChangedConventions.Add(valueGeneratorConvention); conventionSet.ForeignKeyNullNavigationSetConventions.Add(relationshipDiscoveryConvention); var requiredNavigationAttributeConvention = new RequiredNavigationAttributeConvention(Dependencies); var nonNullableNavigationConvention = new NonNullableNavigationConvention(Dependencies); conventionSet.NavigationAddedConventions.Add(new NavigationBackingFieldAttributeConvention(Dependencies)); conventionSet.NavigationAddedConventions.Add(backingFieldConvention); conventionSet.NavigationAddedConventions.Add(requiredNavigationAttributeConvention); conventionSet.NavigationAddedConventions.Add(nonNullableNavigationConvention); conventionSet.NavigationAddedConventions.Add(inversePropertyAttributeConvention); conventionSet.NavigationAddedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.NavigationAddedConventions.Add(relationshipDiscoveryConvention); conventionSet.NavigationAddedConventions.Add(foreignKeyAttributeConvention); var manyToManyJoinEntityTypeConvention = new ManyToManyJoinEntityTypeConvention(Dependencies); conventionSet.SkipNavigationAddedConventions.Add(new NavigationBackingFieldAttributeConvention(Dependencies)); conventionSet.SkipNavigationAddedConventions.Add(backingFieldConvention); conventionSet.SkipNavigationAddedConventions.Add(manyToManyJoinEntityTypeConvention); conventionSet.SkipNavigationRemovedConventions.Add(manyToManyJoinEntityTypeConvention); conventionSet.SkipNavigationInverseChangedConventions.Add(manyToManyJoinEntityTypeConvention); conventionSet.SkipNavigationInverseChangedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.SkipNavigationForeignKeyChangedConventions.Add(manyToManyJoinEntityTypeConvention); conventionSet.SkipNavigationForeignKeyChangedConventions.Add(foreignKeyAttributeConvention); conventionSet.SkipNavigationForeignKeyChangedConventions.Add(keyDiscoveryConvention); conventionSet.SkipNavigationForeignKeyChangedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.NavigationRemovedConventions.Add(relationshipDiscoveryConvention); conventionSet.IndexAddedConventions.Add(foreignKeyIndexConvention); conventionSet.IndexRemovedConventions.Add(foreignKeyIndexConvention); conventionSet.IndexUniquenessChangedConventions.Add(foreignKeyIndexConvention); conventionSet.ForeignKeyPrincipalEndChangedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.ForeignKeyPrincipalEndChangedConventions.Add(requiredNavigationAttributeConvention); conventionSet.ForeignKeyPrincipalEndChangedConventions.Add(nonNullableNavigationConvention); conventionSet.PropertyNullabilityChangedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.PropertyFieldChangedConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.PropertyFieldChangedConventions.Add(keyAttributeConvention); conventionSet.PropertyFieldChangedConventions.Add(concurrencyCheckAttributeConvention); conventionSet.PropertyFieldChangedConventions.Add(databaseGeneratedAttributeConvention); conventionSet.PropertyFieldChangedConventions.Add(requiredPropertyAttributeConvention); conventionSet.PropertyFieldChangedConventions.Add(nonNullableReferencePropertyConvention); conventionSet.PropertyFieldChangedConventions.Add(maxLengthAttributeConvention); conventionSet.PropertyFieldChangedConventions.Add(stringLengthAttributeConvention); conventionSet.PropertyFieldChangedConventions.Add(timestampAttributeConvention); conventionSet.ModelInitializedConventions.Add(new DbSetFindingConvention(Dependencies)); conventionSet.ModelFinalizingConventions.Add(new ModelCleanupConvention(Dependencies)); conventionSet.ModelFinalizingConventions.Add(keyAttributeConvention); conventionSet.ModelFinalizingConventions.Add(indexAttributeConvention); conventionSet.ModelFinalizingConventions.Add(foreignKeyAttributeConvention); conventionSet.ModelFinalizingConventions.Add(new ChangeTrackingStrategyConvention(Dependencies)); conventionSet.ModelFinalizingConventions.Add(new ConstructorBindingConvention(Dependencies)); conventionSet.ModelFinalizingConventions.Add(foreignKeyIndexConvention); conventionSet.ModelFinalizingConventions.Add(foreignKeyPropertyDiscoveryConvention); conventionSet.ModelFinalizingConventions.Add(nonNullableReferencePropertyConvention); conventionSet.ModelFinalizingConventions.Add(nonNullableNavigationConvention); conventionSet.ModelFinalizingConventions.Add(new QueryFilterRewritingConvention(Dependencies)); conventionSet.ModelFinalizingConventions.Add(inversePropertyAttributeConvention); conventionSet.ModelFinalizingConventions.Add(backingFieldConvention); conventionSet.ModelFinalizedConventions.Add(new RuntimeModelConvention(Dependencies)); return(conventionSet); }
private void GenerateProperty(IProperty property, bool useDataAnnotations, IndentedStringBuilder sb) { var lines = new List <string> { $".{nameof(EntityTypeBuilder.Property)}(e => e.{EntityTypeTransformationService.TransformPropertyName(property.Name, property.DeclaringType.Name)})" }; var annotations = AnnotationCodeGenerator .FilterIgnoredAnnotations(property.GetAnnotations()) .ToDictionary(a => a.Name, a => a); AnnotationCodeGenerator.RemoveAnnotationsHandledByConventions(property, annotations); annotations.Remove(ScaffoldingAnnotationNames.ColumnOrdinal); if (useDataAnnotations) { // Strip out any annotations handled as attributes - these are already handled when generating // the entity's properties // Only relational ones need to be removed here. Core ones are already removed by FilterIgnoredAnnotations annotations.Remove(RelationalAnnotationNames.ColumnName); annotations.Remove(RelationalAnnotationNames.ColumnType); _ = AnnotationCodeGenerator.GenerateDataAnnotationAttributes(property, annotations); } else { if (!property.IsNullable && property.ClrType.IsNullableType() && !property.IsPrimaryKey()) { lines.Add($".{nameof(PropertyBuilder.IsRequired)}()"); } var columnType = property.GetConfiguredColumnType(); if (columnType != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasColumnType)}({CSharpHelper.Literal(columnType)})"); annotations.Remove(RelationalAnnotationNames.ColumnType); } var maxLength = property.GetMaxLength(); if (maxLength.HasValue) { lines.Add( $".{nameof(PropertyBuilder.HasMaxLength)}({CSharpHelper.Literal(maxLength.Value)})"); } } var precision = property.GetPrecision(); var scale = property.GetScale(); if (precision != null && scale != null && scale != 0) { lines.Add( $".{nameof(PropertyBuilder.HasPrecision)}({CSharpHelper.Literal(precision.Value)}, {CSharpHelper.Literal(scale.Value)})"); } else if (precision != null) { lines.Add( $".{nameof(PropertyBuilder.HasPrecision)}({CSharpHelper.Literal(precision.Value)})"); } if (property.IsUnicode() != null) { lines.Add( $".{nameof(PropertyBuilder.IsUnicode)}({(property.IsUnicode() == false ? "false" : "")})"); } var defaultValue = property.GetDefaultValue(); if (defaultValue == DBNull.Value) { lines.Add($".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}()"); annotations.Remove(RelationalAnnotationNames.DefaultValue); } else if (defaultValue != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}({CSharpHelper.UnknownLiteral(defaultValue)})"); annotations.Remove(RelationalAnnotationNames.DefaultValue); } var valueGenerated = property.ValueGenerated; var isRowVersion = false; if (((IConventionProperty)property).GetValueGeneratedConfigurationSource() is ConfigurationSource valueGeneratedConfigurationSource && valueGeneratedConfigurationSource != ConfigurationSource.Convention && ValueGenerationConvention.GetValueGenerated(property) != valueGenerated) { var methodName = valueGenerated switch { ValueGenerated.OnAdd => nameof(PropertyBuilder.ValueGeneratedOnAdd), ValueGenerated.OnAddOrUpdate => property.IsConcurrencyToken ? nameof(PropertyBuilder.IsRowVersion) : nameof(PropertyBuilder.ValueGeneratedOnAddOrUpdate), ValueGenerated.OnUpdate => nameof(PropertyBuilder.ValueGeneratedOnUpdate), ValueGenerated.Never => nameof(PropertyBuilder.ValueGeneratedNever), _ => throw new InvalidOperationException(DesignStrings.UnhandledEnumValue($"{nameof(ValueGenerated)}.{valueGenerated}")) }; lines.Add($".{methodName}()"); } if (property.IsConcurrencyToken && !isRowVersion) { lines.Add($".{nameof(PropertyBuilder.IsConcurrencyToken)}()"); } lines.AddRange( AnnotationCodeGenerator.GenerateFluentApiCalls(property, annotations).Select(m => CSharpHelper.Fragment(m)) .Concat(GenerateAnnotations(annotations.Values))); switch (lines.Count) { case 1: return; case 2: lines = new List <string> { lines[0] + lines[1] }; break; } AppendMultiLineFluentApi(property.DeclaringEntityType, lines, sb); }