Entity Framework Core Customize Scaffolding
You can use DbContextWriter & EntityTypeWriter to customize scaffold output.
In newer versions of entity core writers renamed:
- DBContextWriter ==>> CSharpDbContextGenerator
- EntityTypeWriter ==>> CSharpEntityTypeGenerator
Write some custom type writer, you can override everything and you will get your own code generator:
//HERE YOU CAN CHANGE THE WAY TYPES ARE GENERATED AND YOU CAN ADD INTERFACE OR BASE CLASS AS PARENT.
public class CustomEntitiyTypeWriter : EntityTypeWriter
{
public CustomEntitiyTypeWriter([NotNull] CSharpUtilities cSharpUtilities)
: base(cSharpUtilities)
{ }
// Write Code returns generated code for class and you can raplec it with your base class
public override string WriteCode([NotNull] EntityConfiguration entityConfiguration)
{
var classStr = base.WriteCode(entityConfiguration);
var defaultStr = "public partial class " + entityConfiguration.EntityType.Name;
var baseStr = "public partial class " + entityConfiguration.EntityType.Name + " : EntityBase";
classStr = classStr.Replace(defaultStr, baseStr);
return classStr;
}
}
declare it in setup:
public static void ConfigureDesignTimeServices(IServiceCollection services)
=> services.AddSingleton<EntityTypeWriter, CustomEntitiyTypeWriter>();
and then scaffold db, you can do the same for DBContext with CustomDBContextWriter.
@Tornike Choladze's excellent answer led me in the right direction, but in the latest versions of .Net Core (2.0 >) this has to be done a little differently it seems, with regard to the setup.
The custom entity type generator:
class MyEntityTypeGenerator : CSharpEntityTypeGenerator
{
public MyEntityTypeGenerator(ICSharpUtilities cSharpUtilities) : base(cSharpUtilities) { }
public override string WriteCode(IEntityType entityType, string @namespace, bool useDataAnnotations)
{
string code = base.WriteCode(entityType, @namespace, useDataAnnotations);
var oldString = "public partial class " + entityType.Name;
var newString = "public partial class " + entityType.Name + " : EntityBase";
return code.Replace(oldString, newString);
}
}
And the setup, which consists of a class in the same assembly and implementing IDesignTimeServices
:
public class MyDesignTimeServices : IDesignTimeServices
{
public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<ICSharpEntityTypeGenerator, MyEntityTypeGenerator>();
}
}
In case you want to modify entity names (and file and class names) here's something that might help:
Based on Chris Peacock's answer (and comments) you can build two classes to modify the names of entities and files (this works in Core 2.2).
public class CustomEFUtilities : CSharpUtilities
{
public override string Uniquifier(
string proposedIdentifier, ICollection<string> existingIdentifiers)
{
var finalIdentifier = base.Uniquifier(proposedIdentifier, existingIdentifiers);
// your changes here
if (finalIdentifier.StartsWith("tl"))
{
finalIdentifier = finalIdentifier.Substring(2);
}
return finalIdentifier;
}
}
And similarly:
public class CustomEFDesignTimeServices : IDesignTimeServices
{
public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<ICSharpUtilities, CustomEFUtilities>();
}
}
Edit (EF Core 3.1)
A breaking change was introduced (https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/breaking-changes#microsoftentityframeworkcoredesign-is-now-a-developmentdependency-package) so you need to modify your project file:
If you need to reference this package to override EF Core's design-time behavior, then you can update PackageReference item metadata in your project.
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<!-- Remove IncludeAssets to allow compiling against the assembly -->
<!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
</PackageReference>