【问题标题】:Entity Framework 6 Code first Default value overriding the MigrationCodeGeneratorEntity Framework 6 Code first 默认值覆盖 MigrationCodeGenerator
【发布时间】:2018-03-18 00:56:34
【问题描述】:

我发现的所有关于声明默认值的方法都是在 Sql 脚本中生成默认值,而不是在迁移代码中。

我最喜欢使用属性:https://stackoverflow.com/a/34894274/132942

[SqlDefaultValue(DefaultValue = "getutcdate()")]
public DateTime CreatedDateUtc { get; set; }

属性定义

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class SqlDefaultValueAttribute : Attribute
{
    public string DefaultValue { get; set; }
}

在“OnModelCreating”的上下文中添加

modelBuilder.Conventions.Add( new AttributeToColumnAnnotationConvention<SqlDefaultValueAttribute, string>("SqlDefaultValue", (p, attributes) => attributes.Single().DefaultValue));

然后自定义SqlGenerator。但我不喜欢这样,因为在生成迁移时我看不到一切是否符合我的要求。

为此,我像这样修改了 MigrationCodeGeneratorhttps://stackoverflow.com/a/21024108

在自定义的 MigrationCodeGenerator 中

public class ExtendedMigrationCodeGenerator : MigrationCodeGenerator
{
    public override ScaffoldedMigration Generate(string migrationId, IEnumerable<MigrationOperation> operations, string sourceModel, string targetModel, string @namespace, string className)
    {
        foreach (MigrationOperation operation in operations)
        {
            if (operation is CreateTableOperation)
            {
                foreach (var column in ((CreateTableOperation)operation).Columns)
                {
                    System.Data.Entity.Infrastructure.Annotations.AnnotationValues values;
                    if (column.Annotations.TryGetValue("SqlDefaultValue", out values))
                    {
                        column.DefaultValueSql = (string)values.NewValue;
                    }
                }
            }
            else if (operation is AddColumnOperation)
            {
                ColumnModel column = ((AddColumnOperation)operation).Column;

                System.Data.Entity.Infrastructure.Annotations.AnnotationValues values;
                if (column.Annotations.TryGetValue("SqlDefaultValue", out values))
                {
                    column.DefaultValueSql = (string)values.NewValue;
                }

            }
        }

        CSharpMigrationCodeGenerator generator = new CSharpMigrationCodeGenerator();

        return generator.Generate(migrationId, operations, sourceModel, targetModel, @namespace, className);
    }
}

但在 ScaffoldedMigration 方法中,我无法获得自定义注释 SqlDefaultValue 或任何其他注释。

能不能得到这个注解?

【问题讨论】:

  • 您发布的代码按预期工作(我在迁移中得到CreatedDateUtc = c.DateTime(nullable: false, defaultValueSql: "getutcdate()")CreateTable 调用)。你确定你的自定义迁移代码生成器被调用了吗?例如Configuration 类中的行将其设置为 CodeGenerator?

标签: entity-framework entity-framework-6 ef-code-first default-value entity-framework-migrations


【解决方案1】:

您还没有说明您是如何注册要使用的ExtendedMigrationCodeGenerator,您可以在Configuration.csConfiguration 类的构造函数中执行此操作,例如:

public Configuration()
{
    AutomaticMigrationsEnabled = false;
    AutomaticMigrationDataLossAllowed = false;
    // Register the Customized Migration Generator to use
    CodeGenerator = new ExtendedMigrationCodeGenerator();
}

但也不要忘记AlterColumnOperation,如果您将其应用于现有架构,这可能是您最大的问题。

else if (operation is AlterColumnOperation alterColumnOp)
{
    ColumnModel column = alterColumnOp.Column;

    System.Data.Entity.Infrastructure.Annotations.AnnotationValues values;
    if (column.Annotations.TryGetValue("SqlDefaultValue", out values))
    {
        column.DefaultValueSql = (string)values.NewValue;
    }
}

您不会看到生成的输出的另一种情况是,如果在配置自定义ExtendedMigrationCodeGenerator 之前生成的先前迁移中已经应用了约定和注释。

调试提示:

调试自定义迁移逻辑并不像设置断点那么简单,因为它通常由Migration.exe 等外部进程执行。因此,在断点生效之前,我们需要调用调试器,我们可以通过在要调试的位置或迁移代码生成器类的构造函数中插入以下代码来实现:

if (!System.Diagnostics.Debugger.IsAttached)
    System.Diagnostics.Debugger.Launch();

最好附加在构造函数中而不是靠近要调试的代码,因为我们知道构造函数应该在正常情况下执行,但是您的代码无法正常工作的原因可能是由于方法或代码分支根本没有被执行,如果没有被执行,那么Launch()命令也不会被执行。

如果您使用此方法调试迁移并且没有得到调试附加对话框,则说明没有检测到迁移,或者您的ExtendedMigrationCodeGenerator 未正确注册。

【讨论】:

    猜你喜欢
    • 2013-11-02
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多