Skip to content

Commit

Permalink
Merge pull request #194 from gpender/@feature/transform-mapping-impro…
Browse files Browse the repository at this point in the history
…vements

Add .ToTable and .HasColumnName methods when using Transforms.
Generate HasKey if key property transformed.
  • Loading branch information
tonysneed committed Dec 18, 2021
2 parents 2c33f40 + a946d4e commit 2a50b3a
Show file tree
Hide file tree
Showing 6 changed files with 503 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -493,17 +493,25 @@ private void GenerateKey(IKey key, IEntityType entityType, IndentedStringBuilder
if (key.Properties.Count == 1
&& annotations.Count == 0)
{
bool propertyNameOverriden = false;
foreach (var property in key.Properties)
{
var transformedKeyName = EntityTypeTransformationService.TransformPropertyName(entityType, property.Name, property.DeclaringType.Name);
propertyNameOverriden = !property.Name.Equals(transformedKeyName);
if (propertyNameOverriden) break;
}

if (key is IConventionKey concreteKey
&& concreteKey.Properties.SequenceEqual(
KeyDiscoveryConvention.DiscoverKeyProperties(
concreteKey.DeclaringEntityType,
concreteKey.DeclaringEntityType.GetProperties())))
concreteKey.DeclaringEntityType.GetProperties()))
&& UseDataAnnotations || !propertyNameOverriden)
{
return;
}

if (!explicitName
&& UseDataAnnotations)
if (!explicitName && UseDataAnnotations)
{
return;
}
Expand Down Expand Up @@ -534,9 +542,13 @@ private void GenerateTableName(IEntityType entityType, IndentedStringBuilder sb)
var schema = entityType.GetSchema();
var defaultSchema = entityType.Model.GetDefaultSchema();

var transformedTableName = EntityTypeTransformationService.TransformTypeEntityName(tableName);
var tableNameOverriden = tableName != null && !tableName.Equals(transformedTableName);

var explicitSchema = schema != null && schema != defaultSchema;
var explicitTable = explicitSchema || tableName != null && tableName != entityType.GetDbSetName();
if (explicitTable)
if (!explicitTable && tableName != null && tableNameOverriden) explicitTable = true;
if (explicitTable && tableName != null)
{
var parameterString = CSharpHelper.Literal(tableName);
if (explicitSchema)
Expand All @@ -555,7 +567,7 @@ private void GenerateTableName(IEntityType entityType, IndentedStringBuilder sb)
var explicitViewSchema = viewSchema != null && viewSchema != defaultSchema;
var explicitViewTable = explicitViewSchema || viewName != null;

if (explicitViewTable)
if (explicitViewTable && viewName != null)
{
var parameterString = CSharpHelper.Literal(viewName);
if (explicitViewSchema)
Expand Down Expand Up @@ -596,11 +608,16 @@ private void GenerateIndex(IEntityType entityType, IIndex index, IndentedStringB

private void GenerateProperty(IEntityType entityType, IProperty property, bool useDataAnnotations, IndentedStringBuilder sb)
{
var propertyName = EntityTypeTransformationService.TransformPropertyName(entityType, property.Name, property.DeclaringType.Name);
var lines = new List<string>
{
$".{nameof(EntityTypeBuilder.Property)}(e => e.{EntityTypeTransformationService.TransformPropertyName(entityType, property.Name, property.DeclaringType.Name)})"
$".{nameof(EntityTypeBuilder.Property)}(e => e.{propertyName})"
};

// Add .HasColumnName Fluent method for remapped columns where UseDataAnnotations is false
if (!propertyName.Equals(property.Name) && !UseDataAnnotations)
{
lines.Add($".HasColumnName(\"{property.Name}\")");
}
var annotations = AnnotationCodeGenerator
.FilterIgnoredAnnotations(property.GetAnnotations())
.ToDictionary(a => a.Name, a => a);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -532,9 +532,10 @@ private void GenerateKeyAttribute(IProperty property)
private void GenerateColumnAttribute(IProperty property)
{
var columnName = property.GetColumnBaseName();
var propertyName = EntityTypeTransformationService.TransformPropertyName(property.DeclaringEntityType, property.Name, property.DeclaringType.Name);
var columnType = property.GetConfiguredColumnType();

var delimitedColumnName = columnName != null && columnName != property.Name ? CSharpHelper.Literal(columnName) : null;
var delimitedColumnName = columnName != null && columnName != propertyName ? CSharpHelper.Literal(columnName) : null;
var delimitedColumnType = columnType != null ? CSharpHelper.Literal(columnType) : null;

if ((delimitedColumnName ?? delimitedColumnType) != null)
Expand Down
210 changes: 210 additions & 0 deletions test/Scaffolding.Handlebars.Tests/ExpectedContexts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,90 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
}
";
}
private static class ExpectedContextsWithTransformMappings
{
public static string ContextClass =
@"using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
namespace FakeNamespace
{
public partial class FakeDbContext : DbContext
{
public virtual DbSet<CategoryRenamed> Category { get; set; }
public virtual DbSet<ProductRenamed> Product { get; set; }
public FakeDbContext(DbContextOptions<FakeDbContext> options) : base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
optionsBuilder.UseSqlServer(""" + Constants.Connections.SqlServerConnection.Replace(@"\",@"\\") + @""");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<CategoryRenamed>(entity =>
{
entity.HasKey(e => e.CategoryIdRenamed);
entity.ToTable(""Category"");
entity.HasComment(""A category of products"");
entity.Property(e => e.CategoryIdRenamed).HasColumnName(""CategoryId"");
entity.Property(e => e.CategoryNameRenamed)
.HasColumnName(""CategoryName"")
.IsRequired()
.HasMaxLength(15)
.HasComment(""The name of a category"");
});
modelBuilder.Entity<ProductRenamed>(entity =>
{
entity.HasKey(e => e.ProductIdRenamed);
entity.ToTable(""Product"");
entity.HasIndex(e => e.CategoryIdRenamed, ""IX_Product_CategoryId"");
entity.Property(e => e.ProductIdRenamed).HasColumnName(""ProductId"");
entity.Property(e => e.CategoryIdRenamed).HasColumnName(""CategoryId"");
entity.Property(e => e.ProductName)
.IsRequired()
.HasMaxLength(40);
entity.Property(e => e.RowVersion)
.IsRowVersion()
.IsConcurrencyToken();
entity.Property(e => e.UnitPriceRenamed)
.HasColumnName(""UnitPrice"")
.HasColumnType(""money"");
entity.HasOne(d => d.Category)
.WithMany(p => p.Product)
.HasForeignKey(d => d.CategoryIdRenamed);
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
";
}
private static class ExpectedContextsSupressOnConfiguring
{
public static string ContextClass =
Expand Down Expand Up @@ -137,7 +220,81 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
}
";
}
private static class ExpectedContextsSupressOnConfiguringWithTransformMappings
{
public static string ContextClass =
@"using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
namespace FakeNamespace
{
public partial class FakeDbContext : DbContext
{
public virtual DbSet<CategoryRenamed> Category { get; set; }
public virtual DbSet<ProductRenamed> Product { get; set; }
public FakeDbContext(DbContextOptions<FakeDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<CategoryRenamed>(entity =>
{
entity.HasKey(e => e.CategoryIdRenamed);
entity.ToTable(""Category"");
entity.HasComment(""A category of products"");
entity.Property(e => e.CategoryIdRenamed).HasColumnName(""CategoryId"");
entity.Property(e => e.CategoryNameRenamed)
.HasColumnName(""CategoryName"")
.IsRequired()
.HasMaxLength(15)
.HasComment(""The name of a category"");
});
modelBuilder.Entity<ProductRenamed>(entity =>
{
entity.HasKey(e => e.ProductIdRenamed);
entity.ToTable(""Product"");
entity.HasIndex(e => e.CategoryIdRenamed, ""IX_Product_CategoryId"");
entity.Property(e => e.ProductIdRenamed).HasColumnName(""ProductId"");
entity.Property(e => e.CategoryIdRenamed).HasColumnName(""CategoryId"");
entity.Property(e => e.ProductName)
.IsRequired()
.HasMaxLength(40);
entity.Property(e => e.RowVersion)
.IsRowVersion()
.IsConcurrencyToken();
entity.Property(e => e.UnitPriceRenamed)
.HasColumnName(""UnitPrice"")
.HasColumnType(""money"");
entity.HasOne(d => d.Category)
.WithMany(p => p.Product)
.HasForeignKey(d => d.CategoryIdRenamed);
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
";
}
public static class ExpectedContextsWithAnnotations
{
public static string ContextClass =
Expand Down Expand Up @@ -190,5 +347,58 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
}
";
}
public static class ExpectedContextsWithAnnotationsAndTransformMappings
{
public static string ContextClass =
@"using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
namespace FakeNamespace
{
public partial class FakeDbContext : DbContext
{
public virtual DbSet<CategoryRenamed> Category { get; set; }
public virtual DbSet<ProductRenamed> Product { get; set; }
public FakeDbContext(DbContextOptions<FakeDbContext> options) : base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
optionsBuilder.UseSqlServer(""" + Constants.Connections.SqlServerConnection.Replace(@"\",@"\\") + @""");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<CategoryRenamed>(entity =>
{
entity.HasComment(""A category of products"");
entity.Property(e => e.CategoryNameRenamed).HasComment(""The name of a category"");
});
modelBuilder.Entity<ProductRenamed>(entity =>
{
entity.Property(e => e.RowVersion)
.IsRowVersion()
.IsConcurrencyToken();
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}
";
}

}
}

0 comments on commit 2a50b3a

Please sign in to comment.