Skip to content

[Bug] Generated entity ToTable and Property in generated OnModelCreating lack table and column mappings when Handlebars transformers are used #188

@gpender

Description

@gpender

Problems
We are using this library in an ef core database first application and we have some name changes between our database tables and entity names and our column names and entity properties.
We are able to make these mappings changes using the AddHandlebarsTransformers method calls but the fluent code for the context does not correctly add the .ToTable and does not ever add the .AsColumnName.

In addition to this it would be very useful to know the context name when making the transforms against the following methods
entityNameTransformer: MapEntityName,
constructorTransformer: MapPropertyInfo,
propertyTransformer: MapPropertyInfo,
navPropertyTransformer: MapNavPropertyInfo,
entityFileNameTransformer: MapEntityName

Workarounds
We have worked around both of these issues by implementing our own MyHbsCSharpDbContextGenerator with the following code changes:-

Add the IContextTransformationService contextTransformationService to the constructor then execute in the WriteCode override. The contextFileNameTransformer can then store the context locally for use in the other transformers.

public override string WriteCode(IModel model, string contextName, string connectionString, string contextNamespace,
    string modelNamespace, bool useDataAnnotations, bool suppressConnectionStringWarning, bool suppressOnConfiguring)
{
  Check.NotNull(model, nameof(model));
		ContextTransformationService.TransformContextFileName(contextName + ".cs");
		if (!string.IsNullOrEmpty(modelNamespace) && string.CompareOrdinal(contextNamespace, modelNamespace) != 0)
    _modelNamespace = modelNamespace;

  TemplateData = new Dictionary<string, object>();

  if (_options.Value.TemplateData != null)
  {
    foreach (KeyValuePair<string, object> entry in _options.Value.TemplateData)
    {
      TemplateData.Add(entry.Key, entry.Value);
    }
  }

In the GenerateProperty method check for a property name transformation and add the .HasColumnName as necessary.

private void GenerateProperty(IProperty property, bool useDataAnnotations, IndentedStringBuilder sb)
{
  var propertyName =
    EntityTypeTransformationService.TransformPropertyName(property.Name, property.DeclaringType.Name);
  var lines = new List<string>
        {
          $".{nameof(EntityTypeBuilder.Property)}(e => e.{propertyName})"
            //$".{nameof(EntityTypeBuilder.Property)}(e => e.{EntityTypeTransformationService.TransformPropertyName(property.Name, property.DeclaringType.Name)})"
        };
  // Add .HasColumnName Fluent annotation for remapped columns
  if (!propertyName.Equals(property.Name))
  {
    lines.Add($".HasColumnName(\"{property.Name}\")");
  }

In the GenerateTableName method check for a table name transformation in addition to explicitSchema checks

  var explicitTable = explicitSchema || tableName != null && tableName != entityType.GetDbSetName();
  if (tableName != null)
  {
      var overrideName = EntityTypeTransformationService.TransformTypeEntityName(tableName);
      if (!tableName.Equals(overrideName)) explicitTable = true;
  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions