Jason_Hough
Jason_Hough

Reputation: 464

Microsoft.EntityFrameworkCore: No database provider has been configured for this DbContext

I am attempting to put my connection string in the local settings .json file in an Azur e Function (v3) for entity framework core.

I am getting an errors saying.

ystem.Private.CoreLib: Exception while executing function: Function1. Microsoft.EntityFrameworkCore: No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for DbContext.

So I have removed the connection string in OnCofiguration on the context

     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
#warning 
            // optionsBuilder.UseSqlServer("Server=tcp:xxxxx.database.windows.net,1433;Initial Catalog=CatsDB;Persist Security Info=False;User ID=!;Password=!;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;");
            }
        }

I am using Dependency Injection in a startup.cs class :

[assembly: FunctionsStartup(typeof(Startup))]

namespace Shizzle
{
    class Startup : FunctionsStartup
     {
    
      public override void Configure(IFunctionsHostBuilder builder)
      {
          builder.Services.AddDbContext<CatsDBContext>(
                options => options.UseSqlServer(ConfigurationManager.ConnectionStrings["SqlConnectionString"].ConnectionString));
      }
     }

And finally I am storing the connection string in local.settings.json

{
    "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet"
  },
  "ConnectionStrings": {
    "SqlConnectionString": "Server=tcp:xxxx.database.windows.net,1433;Initial Catalog=CatsDB;Persist Security Info=False;User ID=!;Password=0!;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;"
  }
}

and this is the DBContext :

using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;

namespace Shizzle.Models
{
    public partial class CatsDBContext : DbContext
    {
        public CatsDBContext()
        {
        }

        public CatsDBContext(DbContextOptions<CatsDBContext> options)
            : base(options)
        {
        }

Any ideas would be amazing... Thanks

Upvotes: 0

Views: 911

Answers (2)

David Browne - Microsoft
David Browne - Microsoft

Reputation: 89071

This worked for me, but I had to use an ancient EF Core version to be compatible with the current in-process Functions app version (see issue here).

.csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AzureFunctionsVersion>v3</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.6" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.13" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

And the .cs file:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;

[assembly: FunctionsStartup(typeof(FunctionApp5.Startup))]

namespace FunctionApp5
{

    class Startup : FunctionsStartup
    {
        public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
        {
            FunctionsHostBuilderContext context = builder.GetContext();

            var settingsFile = Path.Combine(context.ApplicationRootPath, "local.settingss.json");
            builder.ConfigurationBuilder
                .AddJsonFile(settingsFile, optional: true, reloadOnChange: false);
               // .AddJsonFile(Path.Combine(context.ApplicationRootPath, $"appsettings.{context.EnvironmentName}.json"), optional: true, reloadOnChange: false)
               // .AddEnvironmentVariables();
        }

        public override void Configure(IFunctionsHostBuilder builder)
        {
            
            builder.Services.AddDbContext<CatsDBContext>((sp,options) =>
            {
                var config = sp.GetRequiredService<IConfiguration>();
                var constr = config.GetConnectionString("SqlConnectionString");
                options.UseSqlServer(constr);
             });
        }
    }
    public partial class CatsDBContext : DbContext
    {
        public CatsDBContext()
        {
        }

        public CatsDBContext(DbContextOptions<CatsDBContext> options)
            : base(options)
        {
        }
    }
    public  class Function1
    {
        CatsDBContext db;
        public Function1(CatsDBContext db)
        {
            this.db = db;
        }
        [FunctionName("Function1")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, 
            ILogger log)
        {
            var constr = db.Database.GetDbConnection().ConnectionString;


            log.LogInformation("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            return new OkObjectResult(responseMessage);
        }
    }
}

Upvotes: 0

MB_18
MB_18

Reputation: 2251

The startup.cs class should be

[assembly: FunctionsStartup(typeof(Startup))]

namespace Shizzle
{
    class Startup : FunctionsStartup
     {
    
      public override void Configure(IFunctionsHostBuilder builder)
      {
          builder.Services.AddDbContext<CatsDBContext>(
                options => options.UseSqlServer(Configuration.GetConnectionString("SqlConnectionString")));
      }
 }

Upvotes: 1

Related Questions