My goal is to create a custom Attribute and allow. Add-Migration to have custom code generated based on it.
The Model and Attribute class
public class MyAttribute: Attribute {} public class MyModel { public int Id { get; set; } [MyAttribute] public string Name { get; set; } } The MigrationProvider and AnnotationProvider:
internal class MyMigrationsAnnotationProvider : SqliteMigrationsAnnotationProvider { public override IEnumerable<IAnnotation> For( IProperty property ) { MemberInfo MInfo = property.PropertyInfo ?? ( MemberInfo ) property.FieldInfo; MyAttribute MyAttr = MInfo?.GetCustomAttribute<MyAttribute>(); if ( MyAttr != null ) { return base.For( property ).Concat( new IAnnotation[] { new Annotation( "MyAttribute", true ) } ); } return base.For( property ); } } internal class MyMigrationsSqlGenerator : SqliteMigrationsSqlGenerator { public MyMigrationsSqlGenerator( IRelationalCommandBuilderFactory IRFactory, ISqlGenerationHelper ISHelper, IRelationalTypeMapper Mapper, IRelationalAnnotationProvider AnProvider ) : base( IRFactory, ISHelper, Mapper, AnProvider ) {} protected override void Generate( AddColumnOperation operation, IModel model, MigrationCommandListBuilder builder ) { throw new Exception( "Hello world" ); // Here's where I got it wrong. // I thought I should be able to read the "MyAttribute" annotation from here and generate extra code in the Up method /* if( operation.FindAnnotation( "MyAttribute" ) != null ) { builder.AppendLine( "Hello there, not sure if this would work." ); } */ } } class MyContext : DbContext { public DbSet<MyModel> MModel { get; set; } protected override void OnConfiguring( DbContextOptionsBuilder optionsBuilder ) { optionsBuilder.UseSqlite( "Data Source=mydata.db" ); optionsBuilder.ReplaceService<IMigrationsSqlGenerator, MyMigrationsSqlGenerator>(); optionsBuilder.ReplaceService<IMigrationsAnnotationProvider, MyMigrationsAnnotationProvider>(); } } Generated Migration codes ( with some clean up )
protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable( name: "MyModel", columns: table => new { Id = table.Column<string>(nullable: false), Name = table.Column<string>(nullable: false) .Annotation("MyAttribute", true), }); // The following line is what I want it to be generated migrationBuilder.Sql( "I WANT MY CUSTOM QUERY BE GENERATED HERE" ); } protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( name: "MyModel" ); // The following line is what I want it to be generated migrationBuilder.Sql( "I WANT MY CUSTOM QUERY BE GENERATED HERE" ); } As you can see the MyAttribute annotation is successfully added to the Up method. However, I couldn't seem to override the Generate method since there's no Hello world exception throw while running Add-Migration.
I am using EF Core 1.1.5
Thanks in advance!