use*_*539 6 c# entity-framework entity-framework-core
我的目标是创建自定义Attribute并允许。Add-Migration生成基于它的自定义代码。
模型和Attribute类
public class MyAttribute: Attribute {}
public class MyModel
{
public int Id { get; set; }
[MyAttribute]
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在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>();
}
}
Run Code Online (Sandbox Code Playgroud)
生成的迁移代码(一些清理)
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" );
}
Run Code Online (Sandbox Code Playgroud)
如您所见,MyAttribute注释已成功添加到Up方法中。但是,我似乎无法覆盖该Generate方法,因为Hello world运行时没有异常 throw Add-Migration。
我正在使用 EF Core 1.1.5
提前致谢!
小智 0
问题是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")
}
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
3084 次 |
| 最近记录: |