/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> protected virtual KeyBuilder VisitPrimaryKey([NotNull] EntityTypeBuilder builder, [NotNull] DatabaseTable table) { Check.NotNull(builder, nameof(builder)); Check.NotNull(table, nameof(table)); var primaryKey = table.PrimaryKey; if (primaryKey == null) { _reporter.WriteWarning(DesignStrings.MissingPrimaryKey(table.DisplayName())); return(null); } 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 dummyLogger = new DiagnosticsLogger <DbLoggerCategory.Model>( new ScopedLoggerFactory(new LoggerFactory(), dispose: true), new LoggingOptions(), new DiagnosticListener("")); var conventionalValueGenerated = new RelationalValueGeneratorConvention(dummyLogger).GetValueGenerated(property); if (conventionalValueGenerated == ValueGenerated.OnAdd) { property.ValueGenerated = ValueGenerated.Never; } } } if (!string.IsNullOrEmpty(primaryKey.Name) && primaryKey.Name != ConstraintNamer.GetDefaultName(keyBuilder.Metadata)) { keyBuilder.HasName(primaryKey.Name); } keyBuilder.Metadata.AddAnnotations(primaryKey.GetAnnotations()); return(keyBuilder); }
/// <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 logger = Dependencies.Logger; ValueGeneratorConvention valueGeneratorConvention = new RelationalValueGeneratorConvention(logger); ReplaceConvention(conventionSet.BaseEntityTypeChangedConventions, valueGeneratorConvention); ReplaceConvention(conventionSet.PrimaryKeyChangedConventions, valueGeneratorConvention); ReplaceConvention(conventionSet.ForeignKeyAddedConventions, valueGeneratorConvention); ReplaceConvention(conventionSet.ForeignKeyRemovedConventions, valueGeneratorConvention); var relationalColumnAttributeConvention = new RelationalColumnAttributeConvention(logger); conventionSet.PropertyAddedConventions.Add(relationalColumnAttributeConvention); var sharedTableConvention = new SharedTableConvention(logger); var discriminatorConvention = new DiscriminatorConvention(logger); conventionSet.EntityTypeAddedConventions.Add(new RelationalTableAttributeConvention(logger)); conventionSet.EntityTypeRemovedConventions.Add(discriminatorConvention); conventionSet.BaseEntityTypeChangedConventions.Add(discriminatorConvention); conventionSet.BaseEntityTypeChangedConventions.Add( new TableNameFromDbSetConvention(Dependencies.Context?.Context, Dependencies.SetFinder, logger)); conventionSet.PropertyFieldChangedConventions.Add(relationalColumnAttributeConvention); conventionSet.PropertyAnnotationChangedConventions.Add((RelationalValueGeneratorConvention)valueGeneratorConvention); conventionSet.ModelBuiltConventions.Add(sharedTableConvention); conventionSet.ModelAnnotationChangedConventions.Add(new RelationalDbFunctionConvention(logger)); return(conventionSet); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> protected virtual KeyBuilder VisitPrimaryKey(EntityTypeBuilder builder, DatabaseTable table) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (table == null) { throw new ArgumentNullException(nameof(table)); } var primaryKey = table.PrimaryKey; if (primaryKey == null) { _reporter.WriteWarning(DesignStrings.MissingPrimaryKey(table.DisplayName())); return(null); } var unmappedColumns = primaryKey.Columns .Where(c => _unmappedColumns.Contains(c)) .Select(c => c.Name) .ToList(); if (unmappedColumns.Any()) { _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 = new RelationalValueGeneratorConvention().GetValueGenerated(property); if (conventionalValueGenerated == ValueGenerated.OnAdd) { property.ValueGenerated = ValueGenerated.Never; } } } keyBuilder.Metadata.AddAnnotations(primaryKey.GetAnnotations()); return(keyBuilder); }
/// <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(); ValueGeneratorConvention valueGeneratorConvention = new RelationalValueGeneratorConvention(Dependencies, RelationalDependencies); ReplaceConvention(conventionSet.EntityTypeBaseTypeChangedConventions, valueGeneratorConvention); ReplaceConvention(conventionSet.EntityTypePrimaryKeyChangedConventions, valueGeneratorConvention); ReplaceConvention(conventionSet.ForeignKeyAddedConventions, valueGeneratorConvention); ReplaceConvention(conventionSet.ForeignKeyRemovedConventions, valueGeneratorConvention); var relationalColumnAttributeConvention = new RelationalColumnAttributeConvention(Dependencies, RelationalDependencies); conventionSet.PropertyAddedConventions.Add(relationalColumnAttributeConvention); var storeGenerationConvention = new StoreGenerationConvention(Dependencies, RelationalDependencies); conventionSet.EntityTypeAddedConventions.Add(new RelationalTableAttributeConvention(Dependencies, RelationalDependencies)); conventionSet.EntityTypeBaseTypeChangedConventions.Add(new TableNameFromDbSetConvention(Dependencies, RelationalDependencies)); conventionSet.PropertyFieldChangedConventions.Add(relationalColumnAttributeConvention); conventionSet.PropertyAnnotationChangedConventions.Add(storeGenerationConvention); conventionSet.PropertyAnnotationChangedConventions.Add((RelationalValueGeneratorConvention)valueGeneratorConvention); var sharedTableConvention = new SharedTableConvention(Dependencies, RelationalDependencies); ConventionSet.AddBefore( conventionSet.ModelFinalizedConventions, storeGenerationConvention, typeof(ValidatingConvention)); ConventionSet.AddBefore( conventionSet.ModelFinalizedConventions, sharedTableConvention, typeof(ValidatingConvention)); conventionSet.ModelAnnotationChangedConventions.Add(new RelationalDbFunctionConvention(Dependencies, RelationalDependencies)); return(conventionSet); }
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, 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.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)}" + $"({_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)})"); } } 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)}" + $"({_code.UnknownLiteral(property.GetDefaultValue())})"); } if (property.GetDefaultValueSql() != null) { lines.Add( $".{nameof(RelationalPropertyBuilderExtensions.HasDefaultValueSql)}" + $"({_code.Literal(property.GetDefaultValueSql())})"); } 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 && RelationalValueGeneratorConvention.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 || _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); }