/// <summary> /// Generate entity type data annotations. /// </summary> /// <param name="entityType">Represents an entity type in an <see cref="T:Microsoft.EntityFrameworkCore.Metadata.IModel" />.</param> protected override void GenerateEntityTypeDataAnnotations(IEntityType entityType) { Check.NotNull(entityType, nameof(entityType)); //GenerateTableAttribute(entityType); ClassAnnotationsData = new List <Dictionary <string, object> >(); GenerateKeylessAttribute(entityType); GenerateTableAttribute(entityType); GenerateIndexAttributes(entityType); var annotations = AnnotationCodeGenerator .FilterIgnoredAnnotations(entityType.GetAnnotations()) .ToDictionary(a => a.Name, a => a); AnnotationCodeGenerator.RemoveAnnotationsHandledByConventions(entityType, annotations); foreach (var attribute in AnnotationCodeGenerator.GenerateDataAnnotationAttributes(entityType, annotations)) { var attributeWriter = new AttributeWriter(attribute.Type.Name); foreach (var argument in attribute.Arguments) { attributeWriter.AddParameter(CSharpHelper.UnknownLiteral(argument)); } } TemplateData.Add("class-annotations", ClassAnnotationsData); }
private void GenerateEntityType(IEntityType entityType, bool useDataAnnotations, IndentedStringBuilder sb) { GenerateKey(entityType.FindPrimaryKey(), entityType, useDataAnnotations, sb); var annotations = AnnotationCodeGenerator .FilterIgnoredAnnotations(entityType.GetAnnotations()) .ToDictionary(a => a.Name, a => a); AnnotationCodeGenerator.RemoveAnnotationsHandledByConventions(entityType, annotations); annotations.Remove(RelationalAnnotationNames.TableName); annotations.Remove(RelationalAnnotationNames.Schema); annotations.Remove(RelationalAnnotationNames.ViewName); annotations.Remove(RelationalAnnotationNames.ViewSchema); annotations.Remove(ScaffoldingAnnotationNames.DbSetName); annotations.Remove(RelationalAnnotationNames.ViewDefinitionSql); if (useDataAnnotations) { // Strip out any annotations handled as attributes - these are already handled when generating // the entity's properties _ = AnnotationCodeGenerator.GenerateDataAnnotationAttributes(entityType, annotations); } if (!useDataAnnotations || entityType.GetViewName() != null) { GenerateTableName(entityType, sb); } var lines = new List <string>( AnnotationCodeGenerator.GenerateFluentApiCalls(entityType, annotations).Select(m => CSharpHelper.Fragment(m)) .Concat(GenerateAnnotations(annotations.Values))); AppendMultiLineFluentApi(entityType, lines, sb); foreach (var index in entityType.GetIndexes()) { // If there are annotations that cannot be represented using an IndexAttribute then use fluent API even // if useDataAnnotations is true. var indexAnnotations = AnnotationCodeGenerator .FilterIgnoredAnnotations(index.GetAnnotations()) .ToDictionary(a => a.Name, a => a); AnnotationCodeGenerator.RemoveAnnotationsHandledByConventions(index, indexAnnotations); if (!useDataAnnotations || indexAnnotations.Count > 0) { GenerateIndex(index, sb); } } foreach (var property in entityType.GetProperties()) { GenerateProperty(property, useDataAnnotations, sb); } foreach (var foreignKey in entityType.GetScaffoldForeignKeys(_options.Value)) { GenerateRelationship(foreignKey, useDataAnnotations, sb); } }
/// <summary> /// Generate property data annotations. /// </summary> /// <param name="property">Represents a scalar property of an entity.</param> protected override void GeneratePropertyDataAnnotations(IProperty property) { Check.NotNull(property, nameof(property)); GenerateKeyAttribute(property); GenerateRequiredAttribute(property); GenerateColumnAttribute(property); GenerateMaxLengthAttribute(property); var annotations = AnnotationCodeGenerator .FilterIgnoredAnnotations(property.GetAnnotations()) .ToDictionary(a => a.Name, a => a); AnnotationCodeGenerator.RemoveAnnotationsHandledByConventions(property, annotations); foreach (var attribute in AnnotationCodeGenerator.GenerateDataAnnotationAttributes(property, annotations)) { var attributeWriter = new AttributeWriter(attribute.Type.Name); foreach (var argument in attribute.Arguments) { attributeWriter.AddParameter(CSharpHelper.UnknownLiteral(argument)); } } }
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); }