Search code examples
c#entity-framework-coreazure-functionsentity-framework-migrationsclean-architecture

EFCore migration issue with Azure Function App built using Clean Architecture


I have created an Azure Function App using .Net Core with Clean Architecture as defined here:

This is how my Project Structure looks like:

enter image description here

The Entity Framework is implemented in the Infrastructure Layer and it looks like this:

enter image description here

ApplicationDbContext Code & DI inside Infrastructure

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;
        }
    }
}

And this DI is registered in Azure Function App's Startup class like this:

[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);
        }
    }
}

Here, I'm facing an issue with Migration. I tried the following command:

dotnet ef migrations add "SampleMigration" --project Infrastructure --startup-project FunctionApp --output-dir Persistence\Migrations

But getting this error:

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.

Solution

  • The problem has been resolved with the following code 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);
            }
        }
    }