public void Unmappable_column_type(string StoreType) { var info = new DatabaseModel { Tables = { new DatabaseTable { Name = "E", Columns = { IdColumn }, PrimaryKey = IdPrimaryKey } } }; info.Tables.First() .Columns.Add( new DatabaseColumn { Table = info.Tables.First(), Name = "Coli", StoreType = StoreType }); Assert.Single(_factory.Create(info).FindEntityType("E").GetProperties()); Assert.Single(_reporter.Messages, t => t.Contains(DesignStrings.CannotFindTypeMappingForColumn("E.Coli", StoreType))); }
public void E2ETest_UseAttributesInsteadOfFluentApi() { var filePaths = Generator.Generate( _connectionString, Tables, Enumerable.Empty <string>(), TestProjectDir + Path.DirectorySeparatorChar, // tests that ending DirectorySeparatorChar does not affect namespace TestSubDir, TestNamespace, contextName: "AttributesContext", useDataAnnotations: true, overwriteFiles: false, useDatabaseNames: false); var actualFileSet = new FileSet(InMemoryFiles, Path.GetFullPath(Path.Combine(TestProjectDir, TestSubDir))) { Files = Enumerable.Repeat(filePaths.ContextFile, 1).Concat(filePaths.EntityTypeFiles).Select(Path.GetFileName).ToList() }; var expectedFileSet = new FileSet(new FileSystemFileService(), Path.Combine("ReverseEngineering", "Expected", "Attributes"), contents => contents.Replace("{{connectionString}}", _connectionString)) { Files = new List <string> { "AttributesContext.cs" } .Concat(_expectedEntityTypeFiles).ToList() }; Assert.Contains(_reporter.Messages, m => m.StartsWith("warn: ") && m.Contains("PK__Filtered__")); Assert.Contains("warn: " + DesignStrings.CannotFindTypeMappingForColumn("dbo.AllDataTypes.geographyColumn", "geography"), _reporter.Messages); Assert.Contains("warn: " + DesignStrings.CannotFindTypeMappingForColumn("dbo.AllDataTypes.geometryColumn", "geometry"), _reporter.Messages); Assert.Contains("warn: " + DesignStrings.CannotFindTypeMappingForColumn("dbo.AllDataTypes.hierarchyidColumn", "hierarchyid"), _reporter.Messages); Assert.Contains("warn: " + DesignStrings.CannotFindTypeMappingForColumn("dbo.AllDataTypes.sql_variantColumn", "sql_variant"), _reporter.Messages); Assert.Contains("warn: " + DesignStrings.UnableToScaffoldIndexMissingProperty("IX_UnscaffoldableIndex", "sql_variantColumn,hierarchyidColumn"), _reporter.Messages); Assert.Contains("warn: " + DesignStrings.CannotFindTypeMappingForColumn("dbo.TableWithUnmappablePrimaryKeyColumn.TableWithUnmappablePrimaryKeyColumnID", "hierarchyid"), _reporter.Messages); Assert.Contains("warn: " + DesignStrings.PrimaryKeyErrorPropertyNotFound("dbo.TableWithUnmappablePrimaryKeyColumn", "TableWithUnmappablePrimaryKeyColumnID"), _reporter.Messages); Assert.Contains("warn: " + DesignStrings.UnableToGenerateEntityType("dbo.TableWithUnmappablePrimaryKeyColumn"), _reporter.Messages); Assert.Equal(9, _reporter.Messages.Count(m => m.StartsWith("warn: "))); AssertEqualFileContents(expectedFileSet, actualFileSet); AssertCompile(actualFileSet); }
/// <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 PropertyBuilder VisitColumn([NotNull] EntityTypeBuilder builder, [NotNull] DatabaseColumn column) { Check.NotNull(builder, nameof(builder)); Check.NotNull(column, nameof(column)); var typeScaffoldingInfo = GetTypeScaffoldingInfo(column); if (typeScaffoldingInfo == null) { _unmappedColumns.Add(column); _reporter.WriteWarning( DesignStrings.CannotFindTypeMappingForColumn(column.DisplayName(), column.StoreType)); return(null); } var clrType = typeScaffoldingInfo.ClrType; if (column.IsNullable) { clrType = clrType.MakeNullable(); } if (clrType == typeof(bool) && column.DefaultValueSql != null) { _reporter.WriteWarning( DesignStrings.NonNullableBoooleanColumnHasDefaultConstraint(column.DisplayName())); clrType = clrType.MakeNullable(); } var property = builder.Property(clrType, GetPropertyName(column)); property.HasColumnName(column.Name); if (!typeScaffoldingInfo.IsInferred && !string.IsNullOrWhiteSpace(column.StoreType)) { property.HasColumnType(column.StoreType); } if (typeScaffoldingInfo.ScaffoldUnicode.HasValue) { property.IsUnicode(typeScaffoldingInfo.ScaffoldUnicode.Value); } if (typeScaffoldingInfo.ScaffoldFixedLength == true) { property.IsFixedLength(); } if (typeScaffoldingInfo.ScaffoldMaxLength.HasValue) { property.HasMaxLength(typeScaffoldingInfo.ScaffoldMaxLength.Value); } if (typeScaffoldingInfo.ScaffoldPrecision.HasValue) { if (typeScaffoldingInfo.ScaffoldScale.HasValue) { property.HasPrecision( typeScaffoldingInfo.ScaffoldPrecision.Value, typeScaffoldingInfo.ScaffoldScale.Value); } else { property.HasPrecision(typeScaffoldingInfo.ScaffoldPrecision.Value); } } if (column.ValueGenerated == ValueGenerated.OnAdd) { property.ValueGeneratedOnAdd(); } if (column.ValueGenerated == ValueGenerated.OnUpdate) { property.ValueGeneratedOnUpdate(); } if (column.ValueGenerated == ValueGenerated.OnAddOrUpdate) { property.ValueGeneratedOnAddOrUpdate(); } if (column.DefaultValueSql != null) { property.HasDefaultValueSql(column.DefaultValueSql); } if (column.ComputedColumnSql != null) { property.HasComputedColumnSql(column.ComputedColumnSql, column.ComputedColumnIsStored); } if (column.Comment != null) { property.HasComment(column.Comment); } if (column.Collation != null) { property.HasComment(column.Collation); } if (!(column.Table.PrimaryKey?.Columns.Contains(column) ?? false)) { property.IsRequired(!column.IsNullable); } if ((bool?)column[ScaffoldingAnnotationNames.ConcurrencyToken] == true) { property.IsConcurrencyToken(); } property.Metadata.SetColumnOrdinal(column.Table.Columns.IndexOf(column)); property.Metadata.AddAnnotations( column.GetAnnotations().Where( a => a.Name != ScaffoldingAnnotationNames.ConcurrencyToken)); return(property); }
/// <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 PropertyBuilder VisitColumn(EntityTypeBuilder builder, DatabaseColumn column) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (column == null) { throw new ArgumentNullException(nameof(column)); } var typeScaffoldingInfo = GetTypeScaffoldingInfo(column); if (typeScaffoldingInfo == null) { _unmappedColumns.Add(column); _reporter.WriteWarning( DesignStrings.CannotFindTypeMappingForColumn(column.DisplayName(), column.StoreType)); return(null); } var clrType = typeScaffoldingInfo.ClrType; var forceNullable = typeof(bool) == clrType && column.DefaultValueSql != null; if (forceNullable) { _reporter.WriteWarning( DesignStrings.NonNullableBoooleanColumnHasDefaultConstraint(column.DisplayName())); } if (column.IsNullable || forceNullable) { clrType = clrType.MakeNullable(); } var property = builder.Property(clrType, GetPropertyName(column)); property.HasColumnName(column.Name); if (!typeScaffoldingInfo.IsInferred && !string.IsNullOrWhiteSpace(column.StoreType)) { property.HasColumnType(column.StoreType); } if (typeScaffoldingInfo.ScaffoldUnicode.HasValue) { property.IsUnicode(typeScaffoldingInfo.ScaffoldUnicode.Value); } if (typeScaffoldingInfo.ScaffoldMaxLength.HasValue) { property.HasMaxLength(typeScaffoldingInfo.ScaffoldMaxLength.Value); } if (column.ValueGenerated == ValueGenerated.OnAdd) { property.ValueGeneratedOnAdd(); } if (column.ValueGenerated == ValueGenerated.OnUpdate) { property.ValueGeneratedOnUpdate(); } if (column.ValueGenerated == ValueGenerated.OnAddOrUpdate) { property.ValueGeneratedOnAddOrUpdate(); } if (column.DefaultValueSql != null) { property.HasDefaultValueSql(column.DefaultValueSql); } if (column.ComputedColumnSql != null) { property.HasComputedColumnSql(column.ComputedColumnSql); } if (!(column.Table.PrimaryKey?.Columns.Contains(column) ?? false)) { property.IsRequired(!column.IsNullable && !forceNullable); } if ((bool?)column[ScaffoldingAnnotationNames.ConcurrencyToken] == true) { property.IsConcurrencyToken(); } property.Metadata.Scaffolding().ColumnOrdinal = column.Table.Columns.IndexOf(column); property.Metadata.AddAnnotations( column.GetAnnotations().Where( a => a.Name != ScaffoldingAnnotationNames.UnderlyingStoreType && a.Name != ScaffoldingAnnotationNames.ConcurrencyToken)); return(property); }