首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在EF Core中添加自定义Add-Migration行为?

如何在EF Core中添加自定义Add-Migration行为?
EN

Stack Overflow用户
提问于 2017-12-19 11:01:29
回答 2查看 3.2K关注 0票数 6

我的目标是创建一个自定义的Attribute并允许。Add-Migration可以基于它生成自定义代码。

模型和Attribute

public class MyAttribute: Attribute {}

public class MyModel
{
    public int Id { get; set; }

    [MyAttribute]
    public string Name { get; set; }
}

MigrationProviderAnnotationProvider

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

提前感谢!

EN

回答 2

Stack Overflow用户

发布于 2018-09-17 08:59:43

IMigrationsSqlGenerator只能处理已生成的MigrationOperation。要检测新Attribute中的更改,可能需要替换IMigrationsModelDiffer服务。然后,您可以返回一个新的SqlOperation (或自定义类型),其中包含两个模型之间的其他差异。

从好的方面来说,这意味着你也可以在Down过程中生成撤销操作。

票数 1
EN

Stack Overflow用户

发布于 2018-06-25 01:12:30

问题是,只有在向现有表中添加新列时才会调用AddColumnOperation方法。

对于CreateTable,您需要重写void Generate(CreateTableOperation operation, IModel model, MigrationCommandListBuilder builder)方法。CreateTableOperation包含相同AddColumnOperation类型的操作属性。

下面是一个完整的示例

protected override void Generate(CreateTableOperation operation, IModel model, MigrationCommandListBuilder builder)
{
    base.Generate(operation, model, builder);
    foreach (var columnOperation in operation.Columns) //columnOperation is AddColumnOperation
    {
        //operation.FindAnnotation("MyAttribute")
    }
}

希望这能有所帮助!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47879435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档