Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net core Azure函数使用了错误的DbContext构造函数_Asp.net Core_Entity Framework Core_Azure Functions - Fatal编程技术网

Asp.net core Azure函数使用了错误的DbContext构造函数

Asp.net core Azure函数使用了错误的DbContext构造函数,asp.net-core,entity-framework-core,azure-functions,Asp.net Core,Entity Framework Core,Azure Functions,我有一个现有的EF Core 2.2DbContext,它在ASPNET核心应用程序和LinqPad中都能正常工作。现在我正试图将其添加到Azure函数中。在ASPNET和Azure函数中,我都使用依赖项注入 DbContext类有三个构造函数-一个空构造函数,一个接受连接字符串,另一个接受DbOptionsBuilder实例。ASPNET核心应用程序似乎调用了获取DbOptionsBuilder实例的应用程序,而LinqPad使用了获取连接字符串的应用程序。正如我所说,这两种方法都很好 Azu

我有一个现有的EF Core 2.2
DbContext
,它在ASPNET核心应用程序和LinqPad中都能正常工作。现在我正试图将其添加到Azure函数中。在ASPNET和Azure函数中,我都使用依赖项注入

DbContext
类有三个构造函数-一个空构造函数,一个接受连接字符串,另一个接受
DbOptionsBuilder
实例。ASPNET核心应用程序似乎调用了获取
DbOptionsBuilder
实例的应用程序,而LinqPad使用了获取连接字符串的应用程序。正如我所说,这两种方法都很好

Azure函数应用程序尝试使用接受字符串的函数,但它传递的是null而不是值。这会导致一个错误,即未配置提供程序

通过删除带字符串的构造函数,我可以强制函数应用程序使用
DbOptionsBuilder
构造函数。当我这样做时,功能应用程序工作正常。但是,如果我这样做,我就不能再在LinqPad中使用上下文

我的问题是,首先,我如何使Azure函数调用适当的构造函数而不删除其他构造函数?其次,也不太重要的是,为什么ASPNET运行时和Azure函数运行时的行为不同

编辑 此时我只在本地运行AZ函数,因此它正在从“local.settings.json”文件读取连接字符串。这部分工作正常

下面是函数项目的Startup.Configure方法

public class Startup : FunctionsStartup
{
    /// <summary>
    /// This method gets called by the runtime. Use this method to add services to the DI container.
    /// </summary>
    /// <param name="builder">The function host builder</param>
    public override void Configure(IFunctionsHostBuilder builder)
    {
        // Add database context

        string env = Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT");
        string connectionString = Environment.GetEnvironmentVariable($"ConnectionStrings:{env}");

        builder.Services.AddDbContext<FullContext>(x => x.UseSqlServer(connectionString), ServiceLifetime.Transient);
    }
}
编辑3 查看链接后@Jack Jia建议我尝试以下方法

首先,我创建自己的
DbContextOptionsBuilder
实例,并指定提供程序和连接字符串

    var options = new DbContextOptionsBuilder<FullContext>();
    options.UseSqlServer(connectionString);
但这似乎是可行的:

builder.Services.AddTransient<FullContext>(x => new FullContext(options.Options));
builder.Services.AddTransient(x=>newfullcontext(options.options));
假设我正确理解了文档,那么这两个调用都应该强制DI服务使用构造函数,并使用
DbContextOptions
参数。但情况似乎并非如此。

您可以参考:

如果有多个构造函数,您可以指定一个,如下所示:

Add{LIFETIME}<{SERVICE}>(sp => new {IMPLEMENTATION})
Add{LIFETIME}(sp=>new{IMPLEMENTATION})
例如:

// Constructor1
builder.Services.AddScoped<IMyDep>(sp => new MyDep());

// Constructor2
builder.Services.AddScoped<IMyDep>(sp => new MyDep("A string!"));

// Constructor3
builder.Services.AddScoped<IClass1, Class1>();
builder.Services.AddScoped<IMyDep>(sp =>
{
    IClass1 class1 = sp.GetRequiredService<IClass1>();
    //class1.doSomething(...);
    return new MyDep(class1);
});
//构造函数1
addScope(sp=>newmydep());
//构造器2
AddScoped(sp=>newmydep(“一个字符串!”);
//构造器3
builder.Services.addScope();
builder.Services.addScope(sp=>
{
IClass1 class1=sp.GetRequiredService();
//类别1.剂量测定法(…);
返回新的MyDep(类别1);
});

因此,您不需要更改DbContext类,只需在不同的应用程序中使用不同的构造函数即可

连接字符串值存储在哪里? 我会查来源。开箱即用的asp.net核心具有配置为注入的application.settings.json文件。AZ函数不这样做。 如果您使用的是application.settings.json,则必须将其配置为从该文件加载设置

下面是如何在DI中加载配置文件的示例,该文件允许您具有与asp.net core中类似的内容访问权限:

var config = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory)
                .AddJsonFile("application.settings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables()
                .Build();
builder.Services.AddSingleton<IConfiguration>(config);
var config=new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory)
.AddJsonFile(“application.settings.json”,可选:false,reloadOnChange:true)
.AddenEnvironmentVariables()
.Build();
builder.Services.AddSingleton(配置);
并在Configure方法中获取一个值:
string SqlConnectionString=config.GetConnectionString(“SqlConnectionString”)

这是在
公共覆盖无效配置(IFunctionsHostBuilder)
中完成的。


我能想到的另一种可能性是Azure Key Vault或环境变量。

取决于您注册上下文的方式(您没有显示),如果没有突出显示所做的事情,则很难重现问题,允许更好地理解所询问的内容。谢谢,但问题与获取连接字符串无关。它可以从local.setting.json文件中读取它。问题是.Net使用了错误的构造函数。在DbContext中,构造函数看起来如何?DbContext构造函数可以覆盖DI进程。
public ApplicationDbContext(DbContextOptions):base(options){//在这里执行您需要的任何操作,如Database.EnsureCreated();}
// Constructor1
builder.Services.AddScoped<IMyDep>(sp => new MyDep());

// Constructor2
builder.Services.AddScoped<IMyDep>(sp => new MyDep("A string!"));

// Constructor3
builder.Services.AddScoped<IClass1, Class1>();
builder.Services.AddScoped<IMyDep>(sp =>
{
    IClass1 class1 = sp.GetRequiredService<IClass1>();
    //class1.doSomething(...);
    return new MyDep(class1);
});
var config = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory)
                .AddJsonFile("application.settings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables()
                .Build();
builder.Services.AddSingleton<IConfiguration>(config);