/// <summary> /// Returns the store value generation strategy to set for the given property. /// </summary> /// <param name="property"> The property. </param> /// <returns> The store value generation strategy to set for the given property. </returns> public static new ValueGenerated?GetValueGenerated([NotNull] IProperty property) { var valueGenerated = RelationalValueGenerationConvention.GetValueGenerated(property); if (valueGenerated != null) { return(valueGenerated); } var valueGenerationStrategy = property.GetValueGenerationStrategy(); if (valueGenerationStrategy.HasValue) { switch (valueGenerationStrategy.Value) { case MySQLValueGenerationStrategy.IdentityColumn: return(ValueGenerated.OnAdd); case MySQLValueGenerationStrategy.ComputedColumn: return(ValueGenerated.OnAddOrUpdate); } } return(null); }
/// <summary> /// Builds and returns the convention set for the current database provider. /// </summary> /// <returns> The convention set for the current database provider. </returns> public override ConventionSet CreateConventionSet() { var conventionSet = base.CreateConventionSet(); var relationalColumnAttributeConvention = new RelationalColumnAttributeConvention(Dependencies, RelationalDependencies); conventionSet.PropertyAddedConventions.Add(relationalColumnAttributeConvention); var tableNameFromDbSetConvention = new TableNameFromDbSetConvention(Dependencies, RelationalDependencies); conventionSet.EntityTypeAddedConventions.Add(new RelationalTableAttributeConvention(Dependencies, RelationalDependencies)); conventionSet.EntityTypeAddedConventions.Add(tableNameFromDbSetConvention); ValueGenerationConvention valueGenerationConvention = new RelationalValueGenerationConvention(Dependencies, RelationalDependencies); ReplaceConvention(conventionSet.EntityTypeBaseTypeChangedConventions, valueGenerationConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(tableNameFromDbSetConvention); conventionSet.EntityTypeAnnotationChangedConventions.Add((RelationalValueGenerationConvention)valueGenerationConvention); ReplaceConvention(conventionSet.EntityTypePrimaryKeyChangedConventions, valueGenerationConvention); ReplaceConvention(conventionSet.ForeignKeyAddedConventions, valueGenerationConvention); ReplaceConvention(conventionSet.ForeignKeyRemovedConventions, valueGenerationConvention); conventionSet.PropertyFieldChangedConventions.Add(relationalColumnAttributeConvention); var storeGenerationConvention = new StoreGenerationConvention(Dependencies, RelationalDependencies); conventionSet.PropertyAnnotationChangedConventions.Add(storeGenerationConvention); conventionSet.PropertyAnnotationChangedConventions.Add((RelationalValueGenerationConvention)valueGenerationConvention); var dbFunctionAttributeConvention = new RelationalDbFunctionAttributeConvention(Dependencies, RelationalDependencies); conventionSet.ModelInitializedConventions.Add(dbFunctionAttributeConvention); // ModelCleanupConvention would remove the entity types added by QueryableDbFunctionConvention #15898 ConventionSet.AddAfter( conventionSet.ModelFinalizingConventions, new QueryableDbFunctionConvention(Dependencies, RelationalDependencies), typeof(ModelCleanupConvention)); conventionSet.ModelFinalizingConventions.Add(dbFunctionAttributeConvention); conventionSet.ModelFinalizingConventions.Add(tableNameFromDbSetConvention); conventionSet.ModelFinalizingConventions.Add(storeGenerationConvention); conventionSet.ModelFinalizingConventions.Add(new SharedTableConvention(Dependencies, RelationalDependencies)); conventionSet.ModelFinalizingConventions.Add(new DbFunctionTypeMappingConvention(Dependencies, RelationalDependencies)); ReplaceConvention( conventionSet.ModelFinalizingConventions, (QueryFilterDefiningQueryRewritingConvention) new RelationalQueryFilterDefiningQueryRewritingConvention( Dependencies, RelationalDependencies)); ConventionSet.AddAfter( conventionSet.ModelFinalizedConventions, new RelationalModelConvention(Dependencies, RelationalDependencies), typeof(ValidatingConvention)); return(conventionSet); }
/// <summary> /// Builds and returns the convention set for the current database provider. /// </summary> /// <returns> The convention set for the current database provider. </returns> public override ConventionSet CreateConventionSet() { var conventionSet = base.CreateConventionSet(); ValueGenerationConvention valueGenerationConvention = new RelationalValueGenerationConvention(Dependencies, RelationalDependencies); ReplaceConvention(conventionSet.EntityTypeBaseTypeChangedConventions, valueGenerationConvention); ReplaceConvention(conventionSet.EntityTypePrimaryKeyChangedConventions, valueGenerationConvention); ReplaceConvention(conventionSet.ForeignKeyAddedConventions, valueGenerationConvention); ReplaceConvention(conventionSet.ForeignKeyRemovedConventions, valueGenerationConvention); var relationalColumnAttributeConvention = new RelationalColumnAttributeConvention(Dependencies, RelationalDependencies); conventionSet.PropertyAddedConventions.Add(relationalColumnAttributeConvention); var tableNameFromDbSetConvention = new TableNameFromDbSetConvention(Dependencies, RelationalDependencies); conventionSet.EntityTypeAddedConventions.Add(new RelationalTableAttributeConvention(Dependencies, RelationalDependencies)); conventionSet.EntityTypeAddedConventions.Add(tableNameFromDbSetConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(tableNameFromDbSetConvention); conventionSet.PropertyFieldChangedConventions.Add(relationalColumnAttributeConvention); var storeGenerationConvention = new StoreGenerationConvention(Dependencies, RelationalDependencies); conventionSet.PropertyAnnotationChangedConventions.Add(storeGenerationConvention); conventionSet.PropertyAnnotationChangedConventions.Add((RelationalValueGenerationConvention)valueGenerationConvention); var dbFunctionAttributeConvention = new RelationalDbFunctionAttributeConvention(Dependencies, RelationalDependencies); conventionSet.ModelInitializedConventions.Add(dbFunctionAttributeConvention); conventionSet.ModelAnnotationChangedConventions.Add(dbFunctionAttributeConvention); var sharedTableConvention = new SharedTableConvention(Dependencies, RelationalDependencies); ConventionSet.AddBefore( conventionSet.ModelFinalizedConventions, storeGenerationConvention, typeof(ValidatingConvention)); ConventionSet.AddBefore( conventionSet.ModelFinalizedConventions, sharedTableConvention, typeof(ValidatingConvention)); ConventionSet.AddBefore( conventionSet.ModelFinalizedConventions, new DbFunctionTypeMappingConvention(Dependencies, RelationalDependencies), typeof(ValidatingConvention)); return(conventionSet); }
/// <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 = RelationalValueGenerationConvention.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); }
protected virtual void GenerateProperty(IProperty property, bool useDataAnnotations) { var lines = this.Lines(property); var annotations = property.GetAnnotations().ToList(); RemoveAnnotation(ref annotations, RelationalAnnotationNames.ColumnName); RemoveAnnotation(ref annotations, RelationalAnnotationNames.ColumnType); RemoveAnnotation(ref annotations, CoreAnnotationNames.MaxLength); RemoveAnnotation(ref annotations, CoreAnnotationNames.TypeMapping); RemoveAnnotation(ref annotations, CoreAnnotationNames.Unicode); RemoveAnnotation(ref annotations, RelationalAnnotationNames.DefaultValue); RemoveAnnotation(ref annotations, RelationalAnnotationNames.DefaultValueSql); RemoveAnnotation(ref annotations, RelationalAnnotationNames.Comment); RemoveAnnotation(ref annotations, RelationalAnnotationNames.ComputedColumnSql); RemoveAnnotation(ref annotations, RelationalAnnotationNames.IsFixedLength); RemoveAnnotation(ref annotations, ScaffoldingAnnotationNames.ColumnOrdinal); if (!useDataAnnotations) { if (!property.IsNullable && property.ClrType.IsNullableType() && !property.IsPrimaryKey()) { lines.Add($".{nameof(PropertyBuilder.IsRequired)}()"); } var columnName = property.GetColumnName(); if (columnName != null && columnName != property.Name) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasColumnName)}" + $"({this._code.Literal(columnName)})"); } var columnType = property.GetConfiguredColumnType(); if (columnType != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasColumnType)}" + $"({this._code.Literal(columnType)})"); } var maxLength = property.GetMaxLength(); if (maxLength.HasValue) { lines.Add( $".{nameof(PropertyBuilder.HasMaxLength)}" + $"({this._code.Literal(maxLength.Value)})"); } } if (property.IsUnicode() != null) { lines.Add( $".{nameof(PropertyBuilder.IsUnicode)}" + $"({(property.IsUnicode() == false ? "false" : "")})"); } if (property.IsFixedLength()) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.IsFixedLength)}()"); } if (property.GetDefaultValue() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}" + $"({this._code.UnknownLiteral(property.GetDefaultValue())})"); } if (property.GetDefaultValueSql() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValueSql)}" + $"({this._code.Literal(property.GetDefaultValueSql())})"); } if (property.GetComment() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasComment)}" + $"({this._code.Literal(property.GetComment())})"); } if (property.GetComputedColumnSql() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasComputedColumnSql)}" + $"({this._code.Literal(property.GetComputedColumnSql())})"); } var valueGenerated = property.ValueGenerated; var isRowVersion = false; if (((IConventionProperty)property).GetValueGeneratedConfigurationSource().HasValue && RelationalValueGenerationConvention.GetValueGenerated(property) != valueGenerated) { string methodName; switch (valueGenerated) { case ValueGenerated.OnAdd: methodName = nameof(PropertyBuilder.ValueGeneratedOnAdd); break; case ValueGenerated.OnAddOrUpdate: isRowVersion = property.IsConcurrencyToken; methodName = isRowVersion ? nameof(PropertyBuilder.IsRowVersion) : nameof(PropertyBuilder.ValueGeneratedOnAddOrUpdate); break; case ValueGenerated.Never: methodName = nameof(PropertyBuilder.ValueGeneratedNever); break; default: methodName = ""; break; } lines.Add($".{methodName}()"); } if (property.IsConcurrencyToken && !isRowVersion) { lines.Add($".{nameof(PropertyBuilder.IsConcurrencyToken)}()"); } var annotationsToRemove = new List <IAnnotation>(); foreach (var annotation in annotations) { if (annotation.Value == null || this._annotationCodeGenerator.IsHandledByConvention(property, annotation)) { annotationsToRemove.Add(annotation); } else { var methodCall = this._annotationCodeGenerator.GenerateFluentApi(property, annotation); if (methodCall != null) { lines.Add(this._code.Fragment(methodCall)); annotationsToRemove.Add(annotation); } } } lines.AddRange(this.GenerateAnnotations(annotations.Except(annotationsToRemove))); switch (lines.Count) { case 1: return; case 2: lines = new List <string> { lines[0] + lines[1] }; break; } this.AppendMultiLineFluentApi(property.DeclaringEntityType, lines); }
private void GenerateProperty(IProperty property, bool useDataAnnotations) { var lines = new List <string> { $".{nameof(EntityTypeBuilder.Property)}({_code.Lambda(new [] { property.Name }, " e ")})" }; 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)}" + $"({_code.Literal(columnType)})"); } var maxLength = property.GetMaxLength(); if (maxLength.HasValue) { lines.Add( $".{nameof(PropertyBuilder.HasMaxLength)}" + $"({_code.Literal(maxLength.Value)})"); } } var precision = property.GetPrecision(); var scale = property.GetScale(); if (precision != null && scale != null && scale != 0) { lines.Add( $".{nameof(PropertyBuilder.HasPrecision)}" + $"({_code.Literal(precision.Value)}, {_code.Literal(scale.Value)})"); } else if (precision != null) { lines.Add( $".{nameof(PropertyBuilder.HasPrecision)}" + $"({_code.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)}" + $"({_code.UnknownLiteral(defaultValue)})"); annotations.Remove(RelationalAnnotationNames.DefaultValue); } var valueGenerated = property.ValueGenerated; var isRowVersion = false; if (((IConventionProperty)property).GetValueGeneratedConfigurationSource() is ConfigurationSource valueGeneratedConfigurationSource && valueGeneratedConfigurationSource != ConfigurationSource.Convention && RelationalValueGenerationConvention.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 => _code.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); }
private void GenerateProperty(IProperty property, bool useDataAnnotations) { var lines = new List <string> { $".{nameof(EntityTypeBuilder.Property)}(e => e.{property.Name})" }; var annotations = property.GetAnnotations().ToList(); RemoveAnnotation(ref annotations, CoreAnnotationNames.MaxLength); RemoveAnnotation(ref annotations, CoreAnnotationNames.Precision); RemoveAnnotation(ref annotations, CoreAnnotationNames.Scale); RemoveAnnotation(ref annotations, CoreAnnotationNames.TypeMapping); RemoveAnnotation(ref annotations, CoreAnnotationNames.Unicode); RemoveAnnotation(ref annotations, RelationalAnnotationNames.ColumnName); RemoveAnnotation(ref annotations, RelationalAnnotationNames.ViewColumnName); RemoveAnnotation(ref annotations, RelationalAnnotationNames.ColumnType); RemoveAnnotation(ref annotations, RelationalAnnotationNames.DefaultValue); RemoveAnnotation(ref annotations, RelationalAnnotationNames.DefaultValueSql); RemoveAnnotation(ref annotations, RelationalAnnotationNames.Comment); RemoveAnnotation(ref annotations, RelationalAnnotationNames.ComputedColumnSql); RemoveAnnotation(ref annotations, RelationalAnnotationNames.IsFixedLength); RemoveAnnotation(ref annotations, RelationalAnnotationNames.TableColumnMappings); RemoveAnnotation(ref annotations, RelationalAnnotationNames.ViewColumnMappings); RemoveAnnotation(ref annotations, ScaffoldingAnnotationNames.ColumnOrdinal); if (!useDataAnnotations) { if (!property.IsNullable && property.ClrType.IsNullableType() && !property.IsPrimaryKey()) { lines.Add($".{nameof(PropertyBuilder.IsRequired)}()"); } var columnName = property.GetColumnName(); if (columnName != null && columnName != property.Name) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasColumnName)}" + $"({_code.Literal(columnName)})"); } var viewColumnName = property.GetViewColumnName(); if (viewColumnName != null && viewColumnName != columnName) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasViewColumnName)}" + $"({_code.Literal(columnName)})"); } var columnType = property.GetConfiguredColumnType(); if (columnType != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasColumnType)}" + $"({_code.Literal(columnType)})"); } var maxLength = property.GetMaxLength(); if (maxLength.HasValue) { lines.Add( $".{nameof(PropertyBuilder.HasMaxLength)}" + $"({_code.Literal(maxLength.Value)})"); } } var precision = property.GetPrecision(); var scale = property.GetScale(); if (precision != null && scale != null && scale != 0) { lines.Add( $".{nameof(PropertyBuilder.HasPrecision)}" + $"({_code.Literal(precision.Value)}, {_code.Literal(scale.Value)})"); } else if (precision != null) { lines.Add( $".{nameof(PropertyBuilder.HasPrecision)}" + $"({_code.Literal(precision.Value)})"); } if (property.IsUnicode() != null) { lines.Add( $".{nameof(PropertyBuilder.IsUnicode)}" + $"({(property.IsUnicode() == false ? "false" : "")})"); } if (property.IsFixedLength() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.IsFixedLength)}()"); } if (property.GetDefaultValue() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValue)}" + $"({_code.UnknownLiteral(property.GetDefaultValue())})"); } if (property.GetDefaultValueSql() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValueSql)}" + $"({_code.Literal(property.GetDefaultValueSql())})"); } if (property.GetComment() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasComment)}" + $"({_code.Literal(property.GetComment())})"); } if (property.GetComputedColumnSql() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasComputedColumnSql)}" + $"({_code.Literal(property.GetComputedColumnSql())})"); } var valueGenerated = property.ValueGenerated; var isRowVersion = false; if (((IConventionProperty)property).GetValueGeneratedConfigurationSource().HasValue && RelationalValueGenerationConvention.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)}()"); } var annotationsToRemove = new List <IAnnotation>(); foreach (var annotation in annotations) { if (annotation.Value == null || _annotationCodeGenerator.IsHandledByConvention(property, annotation)) { annotationsToRemove.Add(annotation); } else { var methodCall = _annotationCodeGenerator.GenerateFluentApi(property, annotation); if (methodCall != null) { lines.Add(_code.Fragment(methodCall)); annotationsToRemove.Add(annotation); } } } lines.AddRange(GenerateAnnotations(annotations.Except(annotationsToRemove))); switch (lines.Count) { case 1: return; case 2: lines = new List <string> { lines[0] + lines[1] }; break; } AppendMultiLineFluentApi(property.DeclaringEntityType, lines); }
protected override ValueGenerated?GetValueGenerated(IConventionProperty property) => RelationalValueGenerationConvention.GetValueGenerated(property) ?? (property.GetValueGenerationStrategy() != FbValueGenerationStrategy.None ? ValueGenerated.OnAdd : (ValueGenerated?)null);
/// <summary> /// Builds and returns the convention set for the current database provider. /// </summary> /// <returns> The convention set for the current database provider. </returns> public override ConventionSet CreateConventionSet() { var conventionSet = base.CreateConventionSet(); var relationalColumnAttributeConvention = new RelationalColumnAttributeConvention(Dependencies, RelationalDependencies); var relationalCommentAttributeConvention = new RelationalColumnCommentAttributeConvention(Dependencies, RelationalDependencies); conventionSet.PropertyAddedConventions.Add(relationalColumnAttributeConvention); conventionSet.PropertyAddedConventions.Add(relationalCommentAttributeConvention); var tableNameFromDbSetConvention = new TableNameFromDbSetConvention(Dependencies, RelationalDependencies); conventionSet.EntityTypeAddedConventions.Add(new RelationalTableAttributeConvention(Dependencies, RelationalDependencies)); conventionSet.EntityTypeAddedConventions.Add( new RelationalTableCommentAttributeConvention(Dependencies, RelationalDependencies)); conventionSet.EntityTypeAddedConventions.Add(tableNameFromDbSetConvention); ValueGenerationConvention valueGenerationConvention = new RelationalValueGenerationConvention(Dependencies, RelationalDependencies); ReplaceConvention(conventionSet.EntityTypeBaseTypeChangedConventions, valueGenerationConvention); conventionSet.EntityTypeBaseTypeChangedConventions.Add(tableNameFromDbSetConvention); conventionSet.EntityTypeAnnotationChangedConventions.Add((RelationalValueGenerationConvention)valueGenerationConvention); ReplaceConvention(conventionSet.EntityTypePrimaryKeyChangedConventions, valueGenerationConvention); ReplaceConvention(conventionSet.ForeignKeyAddedConventions, valueGenerationConvention); ReplaceConvention(conventionSet.ForeignKeyRemovedConventions, valueGenerationConvention); conventionSet.PropertyFieldChangedConventions.Add(relationalColumnAttributeConvention); conventionSet.PropertyFieldChangedConventions.Add(relationalCommentAttributeConvention); var storeGenerationConvention = new StoreGenerationConvention(Dependencies, RelationalDependencies); conventionSet.PropertyAnnotationChangedConventions.Add(storeGenerationConvention); conventionSet.PropertyAnnotationChangedConventions.Add((RelationalValueGenerationConvention)valueGenerationConvention); var dbFunctionAttributeConvention = new RelationalDbFunctionAttributeConvention(Dependencies, RelationalDependencies); conventionSet.ModelInitializedConventions.Add(dbFunctionAttributeConvention); // Use TypeMappingConvention to add the relational store type mapping // to the generated concurrency token property ConventionSet.AddBefore( conventionSet.ModelFinalizingConventions, new TableSharingConcurrencyTokenConvention(Dependencies, RelationalDependencies), typeof(TypeMappingConvention)); // ModelCleanupConvention would remove the entity types added by TableValuedDbFunctionConvention #15898 ConventionSet.AddAfter( conventionSet.ModelFinalizingConventions, new TableValuedDbFunctionConvention(Dependencies, RelationalDependencies), typeof(ModelCleanupConvention)); conventionSet.ModelFinalizingConventions.Add(dbFunctionAttributeConvention); conventionSet.ModelFinalizingConventions.Add(tableNameFromDbSetConvention); conventionSet.ModelFinalizingConventions.Add(storeGenerationConvention); conventionSet.ModelFinalizingConventions.Add(new EntityTypeHierarchyMappingConvention(Dependencies, RelationalDependencies)); conventionSet.ModelFinalizingConventions.Add(new SequenceUniquificationConvention(Dependencies, RelationalDependencies)); conventionSet.ModelFinalizingConventions.Add(new SharedTableConvention(Dependencies, RelationalDependencies)); conventionSet.ModelFinalizingConventions.Add(new DbFunctionTypeMappingConvention(Dependencies, RelationalDependencies)); ReplaceConvention( conventionSet.ModelFinalizingConventions, (QueryFilterRewritingConvention) new RelationalQueryFilterRewritingConvention( Dependencies, RelationalDependencies)); ConventionSet.AddAfter( conventionSet.ModelFinalizedConventions, new RelationalModelConvention(Dependencies, RelationalDependencies), typeof(ValidatingConvention)); return(conventionSet); }
/// <summary> /// Create the template output /// </summary> public override string TransformText() { this.Write("using Microsoft.EntityFrameworkCore;\r\nusing Microsoft.EntityFrameworkCore.Metadat" + "a.Builders;\r\nusing "); this.Write(this.ToStringHelper.ToStringWithCulture(ModelNamespace)); this.Write(";\r\n\r\nnamespace "); this.Write(this.ToStringHelper.ToStringWithCulture(Namespace)); this.Write("\r\n{\r\n public class "); this.Write(this.ToStringHelper.ToStringWithCulture(EntityType.Name)); this.Write("Configuration : IEntityTypeConfiguration<"); this.Write(this.ToStringHelper.ToStringWithCulture(EntityType.Name)); this.Write(">\r\n {\r\n public void Configure(EntityTypeBuilder<"); this.Write(this.ToStringHelper.ToStringWithCulture(EntityType.Name)); this.Write("> builder)\r\n {\r\n"); var primaryKey = EntityType.FindPrimaryKey(); if (primaryKey == null) { this.Write(" builder.HasNoKey();\r\n\r\n"); } else if (!Enumerable.SequenceEqual( primaryKey.Properties, KeyDiscoveryConvention.DiscoverKeyProperties( (IConventionEntityType)primaryKey.DeclaringEntityType, primaryKey.DeclaringEntityType.GetProperties().Cast <IConventionProperty>()))) { this.Write(" builder.HasKey("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(primaryKey.Properties))); this.Write(");\r\n\r\n"); } var schema = EntityType.GetSchema(); var scaffoldSchema = schema != null && schema != EntityType.Model.GetDefaultSchema(); var tableName = EntityType.GetTableName(); var isView = EntityType.FindAnnotation("Relational:ViewDefinition") != null; var scaffoldTable = scaffoldSchema || isView || tableName != (string)EntityType["Scaffolding:DbSetName"]; if (scaffoldTable) { this.Write(" builder."); this.Write(this.ToStringHelper.ToStringWithCulture(isView ? "ToView" : "ToTable")); this.Write("("); this.Write(this.ToStringHelper.ToStringWithCulture(scaffoldSchema ? Code.Literal(schema) + ", " : "")); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(tableName))); this.Write(");\r\n\r\n"); } foreach (var index in EntityType.GetIndexes().Where(i => i.IsUnique)) { this.Write(" builder.HasIndex("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(index.Properties))); this.Write(")\r\n .IsUnique();\r\n\r\n"); } foreach (var property in EntityType.GetProperties()) { var originalGenerationEnvironment = GenerationEnvironment; GenerationEnvironment = new StringBuilder(); var columnName = property.GetColumnName(); if (columnName != property.Name) { this.Write(" .HasColumnName("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(columnName))); this.Write(")\r\n"); } var columnType = (string)property["Relational:ColumnType"]; if (columnType != null) { this.Write(" .HasColumnType("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(columnType))); this.Write(")\r\n"); } if (property.IsUnicode() == false) { this.Write(" .IsUnicode(false)\r\n"); } if (property.IsFixedLength() == true) { this.Write(" .IsFixedLength()\r\n"); } if (property.GetDefaultValue() != null || property.GetDefaultValueSql() != null) { this.Write(" .HasDefaultValue()\r\n"); } if (property.GetComputedColumnSql() != null) { this.Write(" .HasComputedColumnSql("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(columnName))); this.Write(")\r\n"); } var valueGenerated = property.ValueGenerated; var isRowVersion = false; if (((IConventionProperty)property).GetValueGeneratedConfigurationSource().HasValue && valueGenerated != RelationalValueGenerationConvention.GetValueGenerated(property)) { if (valueGenerated == ValueGenerated.OnAddOrUpdate && property.IsConcurrencyToken) { isRowVersion = true; this.Write(" .IsRowVersion()\r\n"); } else { this.Write(" .ValueGenerated"); this.Write(this.ToStringHelper.ToStringWithCulture(valueGenerated)); this.Write("()\r\n"); } } if (property.IsConcurrencyToken && !isRowVersion) { this.Write(" .IsConcurrencyToken()\r\n"); } var propertyConfiguration = GenerationEnvironment.ToString(); GenerationEnvironment = originalGenerationEnvironment; if (propertyConfiguration.Length != 0) { this.Write(" builder.Property(e => e."); this.Write(this.ToStringHelper.ToStringWithCulture(property.Name)); this.Write(")\r\n "); this.Write(this.ToStringHelper.ToStringWithCulture(propertyConfiguration.Trim())); this.Write(";\r\n\r\n"); } } foreach (var foreignKey in EntityType.GetForeignKeys()) { var originalGenerationEnvironment = GenerationEnvironment; GenerationEnvironment = new StringBuilder(); if (!foreignKey.PrincipalKey.IsPrimaryKey()) { this.Write(" .HasPrincipalKey"); this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.IsUnique ? "<" + foreignKey.PrincipalEntityType.Name + ">" : "")); this.Write("("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(foreignKey.PrincipalKey.Properties))); this.Write(")\r\n"); } this.Write(" .HasForeignKey"); this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.IsUnique ? "<" + foreignKey.DeclaringEntityType.Name + ">" : "")); this.Write("("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(foreignKey.Properties))); this.Write(")\r\n"); var defaultDeleteBehavior = foreignKey.IsRequired ? DeleteBehavior.Cascade : DeleteBehavior.ClientSetNull; if (foreignKey.DeleteBehavior != defaultDeleteBehavior) { this.Write(" .OnDelete("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(foreignKey.DeleteBehavior))); this.Write(")\r\n"); } var relationshipConfiguration = GenerationEnvironment.ToString(); GenerationEnvironment = originalGenerationEnvironment; this.Write(" builder.HasOne("); this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.DependentToPrincipal != null ? "d => d." + foreignKey.DependentToPrincipal.Name : "")); this.Write(")."); this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.IsUnique ? "WithOne" : "WithMany")); this.Write("("); this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.PrincipalToDependent != null ? "p => p." + foreignKey.PrincipalToDependent.Name : "")); this.Write(")\r\n "); this.Write(this.ToStringHelper.ToStringWithCulture(relationshipConfiguration.Trim())); this.Write(";\r\n\r\n"); } this.Write(" }\r\n }\r\n}\r\n"); return(this.GenerationEnvironment.ToString()); }
public static new ValueGenerated?GetValueGenerated(IProperty property) => RelationalValueGenerationConvention.GetValueGenerated(property) ?? (property.GetValueGenerationStrategy() != FbValueGenerationStrategy.None ? ValueGenerated.OnAdd : (ValueGenerated?)null);
/// <summary> /// Create the template output /// </summary> public override string TransformText() { this.Write("namespace "); this.Write(this.ToStringHelper.ToStringWithCulture(ConfigurationNamespace)); this.Write("\r\n{\r\n using Microsoft.EntityFrameworkCore;\r\n using Microsoft.EntityFramewor" + "kCore.Metadata.Builders;\r\n using Microsoft.EntityFrameworkCore.Storage.ValueC" + "onversion;\r\n using "); this.Write(this.ToStringHelper.ToStringWithCulture(ModelNamespace)); this.Write(";\r\n"); var usingNamespaceEndIndex = GenerationEnvironment.Length; this.Write("\r\n"); var entityTypeComment = EntityType.GetComment(); var originalEntityTypeComment = entityTypeComment?.ToString(); var hasEntityClassInfo = EntityClassInfo.TryGetInfo(ref entityTypeComment, out var entityClassInfo); if (entityTypeComment != null) { this.Write(" /// <summary>\r\n /// "); this.Write(this.ToStringHelper.ToStringWithCulture(entityTypeComment)); this.Write(" Configuration\r\n /// </summary>\r\n"); } this.Write(" public partial class "); this.Write(this.ToStringHelper.ToStringWithCulture(EntityConfigurationName)); this.Write(" : IEntityTypeConfiguration<"); this.Write(this.ToStringHelper.ToStringWithCulture(EntityClassName)); this.Write(">\r\n {\r\n /// <summary>\r\n /// Configure\r\n /// </summary>\r\n " + " public void Configure(EntityTypeBuilder<"); this.Write(this.ToStringHelper.ToStringWithCulture(EntityClassName)); this.Write("> builder)\r\n {\r\n"); var primaryKey = EntityType.FindPrimaryKey(); if (primaryKey == null) { this.Write(" builder.HasNoKey();\r\n\r\n"); } else if (!Enumerable.SequenceEqual( primaryKey.Properties, KeyDiscoveryConvention.DiscoverKeyProperties( (IConventionEntityType)primaryKey.DeclaringEntityType, primaryKey.DeclaringEntityType.GetProperties().Cast <IConventionProperty>()))) { this.Write(" builder.HasKey("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(primaryKey.Properties))); this.Write(")\r\n .HasName(\"PRIMARY\");\r\n\r\n"); } if (!UseDataAnnotations) { var schema = EntityType.GetSchema(); var scaffoldSchema = schema != null && schema != EntityType.Model.GetDefaultSchema(); var tableName = EntityType.GetTableName(); var isView = EntityType.FindAnnotation("Relational:ViewDefinition") != null; var scaffoldTable = scaffoldSchema || isView || tableName != (string)EntityType["Scaffolding:DbSetName"]; if (scaffoldTable) { this.Write(" builder."); this.Write(this.ToStringHelper.ToStringWithCulture(isView ? "ToView" : "ToTable")); this.Write("("); this.Write(this.ToStringHelper.ToStringWithCulture(scaffoldSchema ? Code.Literal(schema) + ", " : string.Empty)); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(tableName))); this.Write(");\r\n\r\n"); } } if (originalEntityTypeComment != null) { this.Write(" builder.HasComment(@\""); this.Write(this.ToStringHelper.ToStringWithCulture(originalEntityTypeComment.Replace("\"", "\"\""))); this.Write("\");\r\n\r\n"); } foreach (var index in EntityType.GetIndexes()) { this.Write(" builder.HasIndex("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(index.Properties))); this.Write(")\r\n"); if (index.IsUnique) { this.Write(" .IsUnique()\r\n"); } this.Write(" .HasName(\""); this.Write(this.ToStringHelper.ToStringWithCulture(index.GetName())); this.Write("\");\r\n\r\n"); } var usingNamespaceSet = new HashSet <string>(); foreach (var property in EntityType.GetProperties()) { var originalGenerationEnvironment = GenerationEnvironment; GenerationEnvironment = new StringBuilder(); var propertyComment = property.GetComment(); var originalPropertyComment = propertyComment?.ToString(); var hasEntityPropertyInfo = EntityPropertyInfo.TryGetInfo(ref propertyComment, out var entityPropertyInfo); var columnName = property.GetColumnName(); if (!UseDataAnnotations) { if (columnName != property.Name) { this.Write(" .HasColumnName("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(columnName))); this.Write(")\r\n"); } var columnType = (string)property["Relational:ColumnType"]; if (columnType != null) { this.Write(" .HasColumnType("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(columnType))); this.Write(")\r\n"); } if (hasEntityPropertyInfo && entityPropertyInfo.Attributes?.Any() == true) { if (entityPropertyInfo.Attributes.Any(item => item.Code == "DatabaseGenerated(DatabaseGeneratedOption.Identity)")) { this.Write(" .ValueGeneratedOnAdd()\r\n"); } if (entityPropertyInfo.Attributes.Any(item => item.Code == "DatabaseGenerated(DatabaseGeneratedOption.Computed)")) { this.Write(" .ValueGeneratedOnAddOrUpdate()\r\n"); } if (entityPropertyInfo.Attributes.Any(item => item.Code == "DatabaseGenerated(DatabaseGeneratedOption.None)")) { this.Write(" .ValueGeneratedNever()\r\n"); } } } if (property.IsUnicode() == false) { this.Write(" .IsUnicode(false)\r\n"); } if (property.IsFixedLength() == true) { this.Write(" .IsFixedLength()\r\n"); } var propertyDefaultValue = property.GetDefaultValue(); if (propertyDefaultValue != null) { this.Write(" .HasDefaultValue("); this.Write(this.ToStringHelper.ToStringWithCulture(propertyDefaultValue)); this.Write(")\r\n"); } var propertyDefaultValueSql = property.GetDefaultValueSql(); if (propertyDefaultValueSql != null) { this.Write(" .HasDefaultValueSql("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(propertyDefaultValueSql))); this.Write(")\r\n"); } var propertyComputedColumnSql = property.GetComputedColumnSql(); if (propertyComputedColumnSql != null) { this.Write(" .HasComputedColumnSql("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(propertyComputedColumnSql))); this.Write(")\r\n"); } var valueGenerated = property.ValueGenerated; var isRowVersion = false; if (((IConventionProperty)property).GetValueGeneratedConfigurationSource().HasValue && valueGenerated != RelationalValueGenerationConvention.GetValueGenerated(property)) { if (valueGenerated == ValueGenerated.OnAddOrUpdate && property.IsConcurrencyToken) { isRowVersion = true; this.Write(" .IsRowVersion()\r\n"); } else { this.Write(" .ValueGenerated"); this.Write(this.ToStringHelper.ToStringWithCulture(valueGenerated)); this.Write("()\r\n"); } } if (property.IsConcurrencyToken && !isRowVersion) { this.Write(" .IsConcurrencyToken()\r\n"); } if (hasEntityPropertyInfo && entityPropertyInfo?.Enum != null) { usingNamespaceSet.Add(entityPropertyInfo.Enum.UsingNamespace); //https://docs.microsoft.com/zh-cn/ef/core/modeling/value-conversions var propertyClrType = property.ClrType; var isNullableType = propertyClrType.IsGenericType && propertyClrType.GetGenericTypeDefinition() == typeof(Nullable <>); var ignoreNullableType = isNullableType ? propertyClrType.GetGenericArguments()[0] : propertyClrType; if (ignoreNullableType == typeof(string)) { this.Write(" .HasConversion(new EnumToStringConverter<"); this.Write(this.ToStringHelper.ToStringWithCulture(entityPropertyInfo.Enum.Name)); this.Write(">())\r\n"); } else { this.Write(" .HasConversion(new EnumToNumberConverter<"); this.Write(this.ToStringHelper.ToStringWithCulture(entityPropertyInfo.Enum.Name)); this.Write(", "); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Reference(ignoreNullableType))); this.Write(">())\r\n"); } } if (originalPropertyComment != null) { this.Write(" .HasComment(@\""); this.Write(this.ToStringHelper.ToStringWithCulture(originalPropertyComment.Replace("\"", "\"\""))); this.Write("\")\r\n"); } var propertyConfiguration = GenerationEnvironment.ToString(); GenerationEnvironment = originalGenerationEnvironment; if (propertyConfiguration.Length != 0) { this.Write(" builder.Property(e => e."); this.Write(this.ToStringHelper.ToStringWithCulture(property.Name)); this.Write(")\r\n "); this.Write(this.ToStringHelper.ToStringWithCulture(propertyConfiguration.Trim())); this.Write(";\r\n\r\n"); } } if (usingNamespaceSet.Any()) { foreach (var usingNamespace in usingNamespaceSet) { if (string.IsNullOrWhiteSpace(usingNamespace)) { continue; } var value = usingNamespace; var prefix = "using "; var thus = " "; if (!value.Trim().StartsWith(prefix)) { value = string.Concat(thus, prefix, value); } var suffix = ";"; if (!value.Trim().EndsWith(suffix)) { value = string.Concat(value, suffix); } value += "\r\n"; GenerationEnvironment.Insert(usingNamespaceEndIndex, value); usingNamespaceEndIndex += value.Length; } } foreach (var foreignKey in EntityType.GetForeignKeys()) { var originalGenerationEnvironment = GenerationEnvironment; GenerationEnvironment = new StringBuilder(); if (!foreignKey.PrincipalKey.IsPrimaryKey()) { this.Write(" .HasPrincipalKey"); this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.IsUnique ? "<" + foreignKey.PrincipalEntityType.Name + ">" : string.Empty)); this.Write("("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(foreignKey.PrincipalKey.Properties))); this.Write(")\r\n"); } this.Write(" .HasForeignKey"); this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.IsUnique ? "<" + foreignKey.DeclaringEntityType.Name + ">" : string.Empty)); this.Write("("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Lambda(foreignKey.Properties))); this.Write(")\r\n"); var defaultDeleteBehavior = foreignKey.IsRequired ? DeleteBehavior.Cascade : DeleteBehavior.ClientSetNull; if (foreignKey.DeleteBehavior != defaultDeleteBehavior) { this.Write(" .OnDelete("); this.Write(this.ToStringHelper.ToStringWithCulture(Code.Literal(foreignKey.DeleteBehavior))); this.Write(")\r\n"); } var relationshipConfiguration = GenerationEnvironment.ToString(); GenerationEnvironment = originalGenerationEnvironment; this.Write(" builder.HasOne("); this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.DependentToPrincipal != null ? "d => d." + foreignKey.DependentToPrincipal.Name : string.Empty)); this.Write(")."); this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.IsUnique ? "WithOne" : "WithMany")); this.Write("("); this.Write(this.ToStringHelper.ToStringWithCulture(foreignKey.PrincipalToDependent != null ? "p => p." + foreignKey.PrincipalToDependent.Name : "")); this.Write(")\r\n "); this.Write(this.ToStringHelper.ToStringWithCulture(relationshipConfiguration.Trim())); this.Write(";\r\n\r\n"); } this.Write(" ConfigurePartial(builder);\r\n }\r\n\r\n partial void Configu" + "rePartial(EntityTypeBuilder<"); this.Write(this.ToStringHelper.ToStringWithCulture(EntityClassName)); this.Write("> builder);\r\n }\r\n}\r\n"); return(this.GenerationEnvironment.ToString()); }