使用 Clean Architecture 构建的 Azure Function App 的 EFCore 迁移问题
EFCore migration issue with Azure Function App built using Clean Architecture
我使用 .Net Core
创建了一个 Azure Function App
和定义的干净架构 here:
这是我的 Project Structure
的样子:
Entity Framework在Infrastructure Layer
中实现,看起来像这样:
基础架构中的 ApplicationDbContext 代码和 DI
namespace AppFunctions.Infrastructure.Persistence
{
public class ApplicationDbContext : DbContext, IApplicationDbContext
{
public ApplicationDbContext(DbContextOptions options) : base(options)
{
}
public DbSet<Product> Products { get; set; }
public Task<int> SaveChangesAsync()
{
return base.SaveChangesAsync();
}
}
}
namespace AppFunctions.Infrastructure
{
public static class DependencyInjection
{
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName)),ServiceLifetime.Transient);
services.AddScoped<IApplicationDbContext>(provider => provider.GetRequiredService<ApplicationDbContext>());
return services;
}
}
}
并且这个 DI 在 Azure Function App's Startup class
中注册是这样的:
[assembly: FunctionsStartup(typeof(StartUp))]
namespace JSStockValuationFrameworkAppFunctions
{
internal class StartUp : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
ConfigureServices(builder.Services);
}
private void ConfigureServices(IServiceCollection services)
{
// Configurations
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile($"local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
services.AddApplication();
services.AddInfrastructure(configuration);
}
}
}
在这里,我遇到了迁移问题。我尝试了以下命令:
dotnet ef migrations add "SampleMigration" --project Infrastructure --startup-project FunctionApp --output-dir Persistence\Migrations
但是出现这个错误:
MSBUILD : error MSB1009: Project file does not exist.
Switch: C:\FrameworkAppFunctions\AppFunctions
Unable to retrieve project metadata. Ensure it's an SDK-style project. If you're using a custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option.
SDK-style project. If you're using a custom BaseIntermediateOutputPath
or MSBuildProjectExtensionsPath values, Use the
--msbuildprojectextensionspath option. ```
- 可以通过运行
dotnet ef dbcontext scaffold <list_of_options>
命令从包含解决方案文件的父文件夹中解决。此外,使用 cd ..
并重新运行将为您提供结果的命令。
- 此外,我可以看到您在命令中使用了反斜杠
\
(Persistence\Migrations
) 全部更改为正斜杠 /
- 有关详细信息,您可以阅读此 link。
问题已通过以下代码解决IDesignTimeDbContextFactory
namespace Infrastructure.Persistence.Configuration
{
public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
{
public ApplicationDbContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsBuilder.UseSqlServer("Connection string goes here...");
return new ApplicationDbContext(optionsBuilder.Options);
}
}
}
我使用 .Net Core
创建了一个 Azure Function App
和定义的干净架构 here:
这是我的 Project Structure
的样子:
Entity Framework在Infrastructure Layer
中实现,看起来像这样:
基础架构中的 ApplicationDbContext 代码和 DI
namespace AppFunctions.Infrastructure.Persistence
{
public class ApplicationDbContext : DbContext, IApplicationDbContext
{
public ApplicationDbContext(DbContextOptions options) : base(options)
{
}
public DbSet<Product> Products { get; set; }
public Task<int> SaveChangesAsync()
{
return base.SaveChangesAsync();
}
}
}
namespace AppFunctions.Infrastructure
{
public static class DependencyInjection
{
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
configuration.GetConnectionString("DefaultConnection"),
b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName)),ServiceLifetime.Transient);
services.AddScoped<IApplicationDbContext>(provider => provider.GetRequiredService<ApplicationDbContext>());
return services;
}
}
}
并且这个 DI 在 Azure Function App's Startup class
中注册是这样的:
[assembly: FunctionsStartup(typeof(StartUp))]
namespace JSStockValuationFrameworkAppFunctions
{
internal class StartUp : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
ConfigureServices(builder.Services);
}
private void ConfigureServices(IServiceCollection services)
{
// Configurations
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile($"local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
services.AddApplication();
services.AddInfrastructure(configuration);
}
}
}
在这里,我遇到了迁移问题。我尝试了以下命令:
dotnet ef migrations add "SampleMigration" --project Infrastructure --startup-project FunctionApp --output-dir Persistence\Migrations
但是出现这个错误:
MSBUILD : error MSB1009: Project file does not exist.
Switch: C:\FrameworkAppFunctions\AppFunctions
Unable to retrieve project metadata. Ensure it's an SDK-style project. If you're using a custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option.
SDK-style project. If you're using a custom BaseIntermediateOutputPath or MSBuildProjectExtensionsPath values, Use the --msbuildprojectextensionspath option. ```
- 可以通过运行
dotnet ef dbcontext scaffold <list_of_options>
命令从包含解决方案文件的父文件夹中解决。此外,使用cd ..
并重新运行将为您提供结果的命令。 - 此外,我可以看到您在命令中使用了反斜杠
\
(Persistence\Migrations
) 全部更改为正斜杠/
- 有关详细信息,您可以阅读此 link。
问题已通过以下代码解决IDesignTimeDbContextFactory
namespace Infrastructure.Persistence.Configuration
{
public class ApplicationDbContextFactory : IDesignTimeDbContextFactory<ApplicationDbContext>
{
public ApplicationDbContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsBuilder.UseSqlServer("Connection string goes here...");
return new ApplicationDbContext(optionsBuilder.Options);
}
}
}