【发布时间】:2017-12-19 03:01:28
【问题描述】:
我的目标是创建一个自定义 Attribute 并允许。 Add-Migration 基于它生成自定义代码。
模型和Attribute 类
public class MyAttribute: Attribute {}
public class MyModel
{
public int Id { get; set; }
[MyAttribute]
public string Name { get; set; }
}
MigrationProvider 和 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>();
}
}
生成的迁移代码(经过一些清理)
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" );
}
如您所见,MyAttribute 注释已成功添加到Up 方法中。但是,我似乎无法覆盖 Generate 方法,因为在运行 Add-Migration 时没有抛出 Hello world 异常。
我使用的是 EF Core 1.1.5
提前致谢!
【问题讨论】:
标签: c# entity-framework entity-framework-core