Reputation: 464
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
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
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