Skip to content

Commit

Permalink
RevEng: Use ScaffoldingTypeMapper
Browse files Browse the repository at this point in the history
  • Loading branch information
smitpatel committed May 31, 2017
1 parent f565d06 commit 8772ea8
Show file tree
Hide file tree
Showing 31 changed files with 187 additions and 25 deletions.
25 changes: 16 additions & 9 deletions src/EFCore.Relational.Design/RelationalScaffoldingModelFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ public class RelationalScaffoldingModelFactory : IScaffoldingModelFactory
private readonly IDatabaseModelFactory _databaseModelFactory;
private readonly HashSet<ColumnModel> _unmappedColumns = new HashSet<ColumnModel>();
private readonly IPluralizer _pluralizer;
private readonly IScaffoldingHelper _scaffoldingHelper;

public RelationalScaffoldingModelFactory(
[NotNull] IDiagnosticsLogger<DbLoggerCategory.Scaffolding> logger,
[NotNull] IRelationalTypeMapper typeMapper,
[NotNull] IDatabaseModelFactory databaseModelFactory,
[NotNull] CandidateNamingService candidateNamingService,
[NotNull] IPluralizer pluralizer)
[NotNull] IPluralizer pluralizer,
[NotNull] IScaffoldingHelper scaffoldingHelper)
{
Check.NotNull(logger, nameof(logger));
Check.NotNull(typeMapper, nameof(typeMapper));
Expand All @@ -55,6 +57,7 @@ public RelationalScaffoldingModelFactory(
CandidateNamingService = candidateNamingService;
_databaseModelFactory = databaseModelFactory;
_pluralizer = pluralizer;
_scaffoldingHelper = scaffoldingHelper;
}

public virtual IModel Create(string connectionString, TableSelectionSet tableSelectionSet)
Expand Down Expand Up @@ -281,34 +284,38 @@ protected virtual PropertyBuilder VisitColumn([NotNull] EntityTypeBuilder builde
Check.NotNull(builder, nameof(builder));
Check.NotNull(column, nameof(column));

var typeMapping = GetTypeMapping(column);
var typeScaffoldingInfo = _scaffoldingHelper.GetTypeScaffoldingInfo(column);

var clrType = typeMapping?.ClrType;
if (clrType == null)
if (typeScaffoldingInfo == null)
{
_unmappedColumns.Add(column);
Logger.ColumnTypeNotMappedWarning(column.DisplayName, column.DataType);
return null;
}

var clrType = typeScaffoldingInfo.ClrType;
if (column.IsNullable)
{
clrType = clrType.MakeNullable();
}

var property = builder.Property(clrType, GetPropertyName(column));

if (TypeMapper.GetMapping(property.Metadata).StoreType != column.DataType
&& !string.IsNullOrWhiteSpace(column.DataType))
property.HasColumnName(column.Name);

if (!typeScaffoldingInfo.IsInferred)
{
property.HasColumnType(column.DataType);
}

property.HasColumnName(column.Name);
if (typeScaffoldingInfo.ScaffoldUnicode == true)
{
property.IsUnicode();
}

if (column.MaxLength.HasValue)
if (typeScaffoldingInfo.ScaffoldMaxLength.HasValue)
{
property.HasMaxLength(column.MaxLength.Value);
property.HasMaxLength(typeScaffoldingInfo.ScaffoldMaxLength.Value);
}

if (column.ValueGenerated == ValueGenerated.OnAdd)
Expand Down
48 changes: 45 additions & 3 deletions src/EFCore.Relational.Design/breakingchanges.netcore.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,55 @@
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.Metadata.ScaffoldingModelAnnotations : Microsoft.EntityFrameworkCore.Metadata.RelationalModelAnnotations",
"MemberId": "public virtual System.String get_UseProviderMethodName()",
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.Metadata.ColumnModel : Microsoft.EntityFrameworkCore.Infrastructure.Annotatable",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.Metadata.DatabaseModel : Microsoft.EntityFrameworkCore.Infrastructure.Annotatable",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.Metadata.ForeignKeyColumnModel : Microsoft.EntityFrameworkCore.Infrastructure.Annotatable",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.Metadata.ForeignKeyModel : Microsoft.EntityFrameworkCore.Infrastructure.Annotatable",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.Metadata.IndexColumnModel : Microsoft.EntityFrameworkCore.Infrastructure.Annotatable",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.Metadata.IndexModel : Microsoft.EntityFrameworkCore.Infrastructure.Annotatable",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.Metadata.ScaffoldingModelAnnotations : Microsoft.EntityFrameworkCore.Metadata.RelationalModelAnnotations",
"MemberId": "public virtual System.Void set_UseProviderMethodName(System.String value)",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.Metadata.ScaffoldingPropertyAnnotations : Microsoft.EntityFrameworkCore.Metadata.RelationalPropertyAnnotations",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.Metadata.SequenceModel : Microsoft.EntityFrameworkCore.Infrastructure.Annotatable",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.Metadata.TableModel : Microsoft.EntityFrameworkCore.Infrastructure.Annotatable",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.ScaffoldingTypeMapper",
"Kind": "Removal"
},
{
"TypeId": "public class Microsoft.EntityFrameworkCore.Scaffolding.TypeScaffoldingInfo",
"Kind": "Removal"
},
{
"TypeId": "public static class Microsoft.EntityFrameworkCore.Metadata.ScaffoldingMetadataExtensions",
"Kind": "Removal"
}
]
3 changes: 3 additions & 0 deletions src/EFCore.Relational/Scaffolding/IScaffoldingHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;

namespace Microsoft.EntityFrameworkCore.Scaffolding
{
public interface IScaffoldingHelper
{
string GetProviderOptionsBuilder([NotNull] string connectionString);

TypeScaffoldingInfo GetTypeScaffoldingInfo([NotNull] ColumnModel columnModel);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ public virtual TypeScaffoldingInfo FindMapping(
bool keyOrIndex,
bool rowVersion)
{
Check.NotEmpty(storeType, nameof(storeType));
// This is because certain providers can have no type specified as a default type e.g. SQLite
Check.NotNull(storeType, nameof(storeType));

var mapping = TypeMapper.FindMapping(storeType);
if (mapping == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public virtual void ConfigureDesignTimeServices(IServiceCollection serviceCollec
.AddSingleton<IScaffoldingModelFactory, SqlServerScaffoldingModelFactory>()
.AddSingleton<IRelationalTypeMapper, SqlServerTypeMapper>()
.AddSingleton<IDatabaseModelFactory, SqlServerDatabaseModelFactory>()
.AddSingleton<IScaffoldingHelper, SqlServerScaffoldingHelper>();
.AddSingleton<IScaffoldingHelper, SqlServerScaffoldingHelper>()
.AddSingleton<ScaffoldingTypeMapper>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ public SqlServerScaffoldingModelFactory(
[NotNull] IRelationalTypeMapper typeMapper,
[NotNull] IDatabaseModelFactory databaseModelFactory,
[NotNull] CandidateNamingService candidateNamingService,
[NotNull] IPluralizer pluralizer)
: base(logger, typeMapper, databaseModelFactory, candidateNamingService, pluralizer)
[NotNull] IPluralizer pluralizer,
[NotNull] IScaffoldingHelper scaffoldingHelper)
: base(logger, typeMapper, databaseModelFactory, candidateNamingService, pluralizer, scaffoldingHelper)
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,56 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata.Internal;
using Microsoft.EntityFrameworkCore.Utilities;

namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal
{
public class SqlServerScaffoldingHelper : IScaffoldingHelper
{
private readonly ScaffoldingTypeMapper _scaffoldingTypeMapper;

public SqlServerScaffoldingHelper([NotNull] ScaffoldingTypeMapper scaffoldingTypeMapper)
{
Check.NotNull(scaffoldingTypeMapper, nameof(scaffoldingTypeMapper));

_scaffoldingTypeMapper = scaffoldingTypeMapper;
}

public virtual string GetProviderOptionsBuilder(string connectionString)
{
return $"{nameof(SqlServerDbContextOptionsExtensions.UseSqlServer)}({CSharpUtilities.Instance.GenerateVerbatimStringLiteral(connectionString)});";
}

public virtual TypeScaffoldingInfo GetTypeScaffoldingInfo(ColumnModel columnModel)
{
if (columnModel.DataType == null)
{
return null;
}

string underlyingDataType = null;
columnModel.Table.Database.SqlServer().TypeAliases?.TryGetValue(
SchemaQualifiedKey(columnModel.DataType, columnModel.SqlServer().DataTypeSchemaName), out underlyingDataType);

var dataType = underlyingDataType ?? (columnModel.DataType + (columnModel.MaxLength.HasValue ? $"({columnModel.MaxLength.Value})" : ""));

var typeScaffoldingInfo = _scaffoldingTypeMapper.FindMapping(dataType, keyOrIndex: false, rowVersion: false);

if (underlyingDataType != null)
{
return new TypeScaffoldingInfo(
typeScaffoldingInfo.ClrType,
inferred: false,
scaffoldUnicode: typeScaffoldingInfo.ScaffoldUnicode,
scaffoldMaxLength: typeScaffoldingInfo.ScaffoldMaxLength);
}

return typeScaffoldingInfo;
}

private static string SchemaQualifiedKey(string name, string schema = null) => "[" + (schema ?? "") + "].[" + name + "]";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public virtual void ConfigureDesignTimeServices(IServiceCollection serviceCollec
=> serviceCollection
.AddSingleton<IRelationalTypeMapper, SqliteTypeMapper>()
.AddSingleton<IDatabaseModelFactory, SqliteDatabaseModelFactory>()
.AddSingleton<IScaffoldingHelper, SqliteScaffoldingHelper>();
.AddSingleton<IScaffoldingHelper, SqliteScaffoldingHelper>()
.AddSingleton<ScaffoldingTypeMapper>();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;
using Microsoft.EntityFrameworkCore.Utilities;

namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal
{
public class SqliteScaffoldingHelper : IScaffoldingHelper
{
private readonly ScaffoldingTypeMapper _scaffoldingTypeMapper;

public SqliteScaffoldingHelper([NotNull] ScaffoldingTypeMapper scaffoldingTypeMapper)
{
Check.NotNull(scaffoldingTypeMapper, nameof(scaffoldingTypeMapper));

_scaffoldingTypeMapper = scaffoldingTypeMapper;
}

public virtual string GetProviderOptionsBuilder(string connectionString)
{
return $"{nameof(SqliteDbContextOptionsBuilderExtensions.UseSqlite)}({CSharpUtilities.Instance.GenerateVerbatimStringLiteral(connectionString)});";
}

public virtual TypeScaffoldingInfo GetTypeScaffoldingInfo(ColumnModel columnModel)
{
if (columnModel.DataType == null)
{
return null;
}

var dataType = columnModel.DataType + (columnModel.MaxLength.HasValue ? $"({columnModel.MaxLength.Value})" : "");

var typeScaffoldingInfo = _scaffoldingTypeMapper.FindMapping(dataType, keyOrIndex: false, rowVersion: false);

if (columnModel.DataType == "")
{
return new TypeScaffoldingInfo(
typeScaffoldingInfo.ClrType,
inferred: true,
scaffoldUnicode: typeScaffoldingInfo.ScaffoldUnicode,
scaffoldMaxLength: typeScaffoldingInfo.ScaffoldMaxLength);
}

return typeScaffoldingInfo;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.ReverseEngineering;
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;
using Microsoft.EntityFrameworkCore.TestUtilities;
using Xunit;

Expand Down Expand Up @@ -51,6 +52,11 @@ public string GetProviderOptionsBuilder(string connectionString)
{
throw new NotImplementedException();
}

public TypeScaffoldingInfo GetTypeScaffoldingInfo(ColumnModel columnModel)
{
throw new NotImplementedException();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public RelationalDatabaseModelFactoryTest()
_factory = new FakeScaffoldingModelFactory(
new DiagnosticsLogger<DbLoggerCategory.Scaffolding>(
loggerFactory,
new LoggingOptions(),
new LoggingOptions(),
new DiagnosticListener("Fake")));
}

Expand Down Expand Up @@ -104,8 +104,7 @@ public void Loads_column_types()
{
Name = "salary",
DataType = "long",
IsNullable = true,
MaxLength = 100
IsNullable = true
},
new ColumnModel
{
Expand Down Expand Up @@ -169,7 +168,6 @@ public void Loads_column_types()
Assert.Equal("Salary", col5.Name);
Assert.Equal(typeof(long?), col5.ClrType);
Assert.True(col5.IsColumnNullable());
Assert.Equal(100, col5.GetMaxLength());
Assert.Null(col5.Relational().DefaultValue);
});
}
Expand Down Expand Up @@ -905,7 +903,7 @@ public void Pluralization_of_entity_and_DbSet()
var factory = new FakeScaffoldingModelFactory(
new DiagnosticsLogger<DbLoggerCategory.Scaffolding>(
new TestDesignLoggerFactory(),
new LoggingOptions(),
new LoggingOptions(),
new DiagnosticListener("Fake")),
new FakePluralizer());

Expand Down Expand Up @@ -1007,8 +1005,31 @@ public FakeScaffoldingModelFactory(
new TestTypeMapper(new RelationalTypeMapperDependencies()),
new FakeDatabaseModelFactory(),
new CandidateNamingService(),
pluralizer)
pluralizer,
new FakeScaffoldingHelper())
{
}
}

public class FakeScaffoldingHelper : IScaffoldingHelper
{
public string GetProviderOptionsBuilder(string connectionString)
{
throw new NotImplementedException();
}

public TypeScaffoldingInfo GetTypeScaffoldingInfo(ColumnModel columnModel)
{
if (columnModel.DataType == null)
{
return null;
}

var dataType = columnModel.DataType + (columnModel.MaxLength.HasValue ? $"({columnModel.MaxLength.Value})" : "");

var scaffoldingTypeMapper = new ScaffoldingTypeMapper(new TestTypeMapper(new RelationalTypeMapperDependencies()));

return scaffoldingTypeMapper.FindMapping(dataType, keyOrIndex: false, rowVersion: false);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public void It_loads_column_types()
Assert.NotNull(entityType);
Assert.Equal("Column Types", entityType.Sqlite().TableName);

Assert.Equal("text", entityType.FindProperty("Col1").Sqlite().ColumnType);
Assert.Null(entityType.FindProperty("Col1").Sqlite().ColumnType);
Assert.Equal(typeof(string), entityType.FindProperty("Col1").ClrType);

Assert.Equal("unsigned big int", entityType.FindProperty("Col2").Sqlite().ColumnType);
Expand Down

0 comments on commit 8772ea8

Please sign in to comment.