gpt4 book ai didi

c# - 如何在 EF Core 中添加自定义添加迁移行为?

转载 作者:行者123 更新时间:2023-11-30 12:55:33 25 4
gpt4 key购买 nike

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

模型和属性

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

提前致谢!

最佳答案

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

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

关于c# - 如何在 EF Core 中添加自定义添加迁移行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47879435/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com