【问题标题】:Debugging Code Called by EF Core Add-MigrationsEF Core Add-Migrations 调用的调试代码
【发布时间】:2018-08-24 22:04:29
【问题描述】:

我使用 IDesignTimeDbContextFactory 模式在单独的程序集中定义了一个 Entity Framework Core 数据库(即,我定义了一个派生自 IDesignTimeDbContextFactory 的类,该类有一个名为 CreateDbContext 的方法,该方法返回数据库上下文的一个实例)。

由于 EF Core 数据库所属的应用程序利用 AutoFac 依赖注入,因此 IDesignTimeDbContextFactory 工厂类在其构造函数中创建一个 AutoFac 容器,然后解析馈入构造函数的 DbContextOptionsBuilder 派生类对于数据库上下文(我这样做是为了根据配置文件设置来控制是针对本地还是基于 Azure 的 SqlServer 数据库,并将密码存储在 Azure KeyVault 中):

public class TemporaryDbContextFactory : IDesignTimeDbContextFactory<FitchTrustContext>
{
    private readonly FitchTrustDBOptions _dbOptions;

    public TemporaryDbContextFactory()
    {
        // OMG, I would >>never<< have thought to do this to eliminate the default logging by this
        // deeply-buried package. Thanx to Bruce Chen via 
        // https://stackoverflow.com/questions/47982194/suppressing-console-logging-by-azure-keyvault/48016958#48016958
        LoggerCallbackHandler.UseDefaultLogging = false;

        var builder = new ContainerBuilder();

        builder.RegisterModule<SerilogModule>();
        builder.RegisterModule<KeyVaultModule>();
        builder.RegisterModule<ConfigurationModule>();
        builder.RegisterModule<FitchTrustDbModule>();

        var container = builder.Build();

        _dbOptions = container.Resolve<FitchTrustDBOptions>() ??
                     throw new NullReferenceException(
                         $"Could not resolve {typeof(FitchTrustDBOptions).Name}");
    }

    public FitchTrustContext CreateDbContext( string[] args )
    {
        return new FitchTrustContext( _dbOptions );
    }
}

public class FitchTrustDBOptions : DbContextOptionsBuilder<FitchTrustContext>
{
    public FitchTrustDBOptions(IFitchTrustNGConfigurationFactory configFactory, IKeyVaultManager kvMgr)
    {
        if (configFactory == null)
            throw new NullReferenceException(nameof(configFactory));

        if (kvMgr == null)
            throw new NullReferenceException(nameof(kvMgr));

        var scannerConfig = configFactory.GetFromDisk()
                            ?? throw new NullReferenceException(
                                "Could not retrieve ScannerConfiguration from disk");

        var dbConnection = scannerConfig.Database.Connections
                               .SingleOrDefault(c =>
                                   c.Location.Equals(scannerConfig.Database.Location,
                                       StringComparison.OrdinalIgnoreCase))
                           ?? throw new ArgumentOutOfRangeException(
                               $"Cannot find database connection information for location '{scannerConfig.Database.Location}'");

        var temp = kvMgr.GetSecret($"DatabaseCredentials--{dbConnection.Location}--Password");

        var connString = String.IsNullOrEmpty(dbConnection.UserID) || String.IsNullOrEmpty(temp)
            ? dbConnection.ConnectionString
            : $"{dbConnection.ConnectionString}; User ID={dbConnection.UserID}; Password={temp}";

        this.UseSqlServer(connString,
            optionsBuilder =>
                optionsBuilder.MigrationsAssembly(typeof(FitchTrustContext).GetTypeInfo().Assembly.GetName()
                    .Name));
    }
}

不用说,虽然这为我提供了很大的灵活性(我可以通过更改单个配置参数从本地切换到云数据库,并且任何所需的密码都合理安全地存储在云中),但它可能会出错如果代码中存在错误(例如,配置文件的名称错误),则添加迁移命令行开关。

为了调试这类问题,我经常不得不求助于通过诊断 WriteLine 调用将消息输出到 Visual Studio 输出窗口。这让我觉得很原始(更不用说费时了)。

有没有办法将调试器附加到由 add-migration 调用的代码中,以便我可以逐步完成它、检查值等?我尝试在我的代码中插入 Launch() 调试器行,但它不起作用。这似乎让我进入了 add-manager 代码库,我没有为其加载任何符号,并且我尝试在代码中设置的断点显示为空的红色圆圈:它们永远不会被命中。

欢迎提出想法和建议!

【问题讨论】:

    标签: entity-framework-core entity-framework-core-migrations


    【解决方案1】:

    Debugger.Launch() 添加到构造函数的开头以启动即时调试器。这使您可以将 VS 附加到进程并像往常一样对其进行调试。

    【讨论】:

    • 这与将 Debugger.Launch() 放在 add-migrations 调用的代码中的任何其他位置有何不同?我已经完成了,导致永远无法命中我在尝试调试的代码中设置的断点。
    • 抱歉,错过了那一段。不知道为什么它不起作用...尝试添加一个长的 Thread.Sleep() 让您有时间附加到 dotnet.exe(或 ef.exe)
    猜你喜欢
    • 2022-01-08
    • 1970-01-01
    • 2017-05-30
    • 2022-08-22
    • 2018-04-18
    • 2021-04-05
    • 2022-07-19
    • 2018-05-08
    • 2019-11-20
    相关资源
    最近更新 更多