Closed AmilaDotDev closed 5 years ago
Your best bet I think is to create a class that extends HbsCSharpEntityTypeGenerator
and then override the GenerateProperties
method. This method accepts an IEntityType
, which has all the info you need, including the name of the entity that corresponds to the db table name. Start by copying code from the base GenerateProperties method and modify it to take into account the entity name when setting the property name.
Let me know if this makes sense.
If you decide this approach works for you, you'll have a class like so:
public class MyCSharpEntityTypeGenerator : HbsCSharpEntityTypeGenerator
{
public MyCSharpEntityTypeGenerator(IEntityTypeTemplateService entityTypeTemplateService, IEntityTypeTransformationService entityTypeTransformationService, ICSharpHelper cSharpHelper) : base(entityTypeTemplateService, entityTypeTransformationService, cSharpHelper)
{
}
protected override void GenerateProperties(IEntityType entityType)
{
if (entityType == null) throw new ArgumentNullException(nameof(entityType));
var properties = new List<Dictionary<string, object>>();
foreach (var property in entityType.GetProperties().OrderBy(p => p.Scaffolding().ColumnOrdinal))
{
PropertyAnnotationsData = new List<Dictionary<string, object>>();
if (UseDataAnnotations)
{
GeneratePropertyDataAnnotations(property);
}
// Custom logic here
var propertyName = property.Name;
if (entityType.Name.Equals("SpecialTable", StringComparison.InvariantCultureIgnoreCase)
|| property.Name.Equals("Type", StringComparison.InvariantCultureIgnoreCase))
{
propertyName = "SpecialType";
}
else if (entityType.Name.Equals("OtherSpecialTable", StringComparison.InvariantCultureIgnoreCase))
{
propertyName = "OtherType";
}
properties.Add(new Dictionary<string, object>
{
{ "property-type", CSharpHelper.Reference(property.ClrType) },
{ "property-name", propertyName },
{ "property-annotations", PropertyAnnotationsData }
});
}
var transformedProperties = EntityTypeTransformationService.TransformProperties(properties);
TemplateData.Add("properties", transformedProperties);
}
}
Then you'll need to register the class with the DI system, by adding code to your ScaffoldingDesignTimeServices
class, like so:
public class ScaffoldingDesignTimeServices : IDesignTimeServices
{
public void ConfigureDesignTimeServices(IServiceCollection services)
{
// Normal code to register handlebars templates (omitted here)
// Add custom entity type generator
services.AddSingleton<ICSharpEntityTypeGenerator, MyCSharpEntityTypeGenerator>();
Hope this helps!
Thanks for the detailed response @tonysneed, I'll report back after trying this.
That worked like a charm, had to take nullable into account when changing the type.
private string GetPropertyType(IEntityType entityType, IProperty property)
{
var propertyType = CSharpHelper.Reference(property.ClrType);
var newPropertyType = propertyType;
var propertyName = property.Name;
switch (propertyName)
{
case "Type":
{
switch (entityType.Name)
{
case "Address":
newPropertyType = nameof(AddressType);
break;
case "BaseAddress":
newPropertyType = nameof(BaseAddressType);
break;
}
}
break;
}
return property.IsNullable && !propertyType.Equals(newPropertyType) ? $"{newPropertyType}?" : newPropertyType;
}
Then used it in
properties.Add(new Dictionary<string, object>
{
{ "property-type", GetPropertyType(entityType , property) },
{ "property-name", propertyName },
{ "property-annotations", PropertyAnnotationsData }
});
Thanks @tonysneed
Glad it worked!
Hi,
Thanks for this great library.
Taking the example you've given in the README, is there a way to detect the table it's running on?
services.AddHandlebarsTransformers( propertyTransformer: e => e.PropertyName == "Country" ? new EntityPropertyInfo("Country", e.PropertyName) : new EntityPropertyInfo(e.PropertyType, e.PropertyName));
The problem I'm having is I have a property named
Type
in multiple tables and I want to change the property type depending on which class/table it is on.Is this possible using
propertyTransformer
or is there another way to achieve this?Thanks