Entity framework ASP.NET核心构造函数

Entity framework ASP.NET核心构造函数,entity-framework,asp.net-core,asp.net5,Entity Framework,Asp.net Core,Asp.net5,我在.NET5中使用ASP.NETCore,最近想从本地开发模式更改为Azure Web生产模式 在本地我使用SQLite,一切正常,在生产上我想使用Azure SQL。 但是,当我想迁移数据库时,会出现一个相当长的异常: System.Exception: Could not resolve a service of type 'Server.Calendars.CalendarDataContext' for the parameter 'calendarDataContext' of me

我在.NET5中使用ASP.NETCore,最近想从本地开发模式更改为Azure Web生产模式

在本地我使用SQLite,一切正常,在生产上我想使用Azure SQL。 但是,当我想迁移数据库时,会出现一个相当长的异常:

System.Exception: Could not resolve a service of type 'Server.Calendars.CalendarDataContext' for the parameter 'calendarDataContext' of method 'Configure' on type 'Server.Startup'.
 ---> System.InvalidOperationException: Unable to activate type 'Server.Calendars.CalendarDataContext'. The following constructors are ambiguous:
Void .ctor(Microsoft.Extensions.Configuration.IConfiguration)
Void .ctor(Microsoft.EntityFrameworkCore.DbContextOptions`1[Server.Calendars.CalendarDataContext])
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, Int32 slot)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.<>c__DisplayClass7_0.<GetCallSite>b__0(Type type)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.GetCallSite(Type serviceType, CallSiteChain callSiteChain)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.CreateServiceAccessor(Type serviceType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
   at Microsoft.AspNetCore.Hosting.ConfigureBuilder.<>c__DisplayClass4_0.<Build>b__0(IApplicationBuilder builder)
   at Microsoft.AspNetCore.Hosting.GenericWebHostBuilder.<>c__DisplayClass15_0.<UseStartup>b__1(IApplicationBuilder app)
   at Microsoft.Extensions.DependencyInjection.AutoRegisterMiddleware.<>c__DisplayClass4_0.<Configure>b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilderStartupFilter.<>c__DisplayClass0_0.<Configure>g__MiddlewareFilterBuilder|0(IApplicationBuilder builder)
   at Microsoft.AspNetCore.Server.IIS.Core.IISServerSetupFilter.<>c__DisplayClass2_0.<Configure>b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder app)
   at Microsoft.AspNetCore.Hosting.GenericWebHostService.StartAsync(CancellationToken cancellationToken)
Azure SQL的我的类
CalendarDataContext.cs

public class CalendarDataContext : DbContext
{
    public DbSet<CalendarEntry> CalendarEntries { get; set; }


    protected readonly IConfiguration Configuration;

    public CalendarDataContext(IConfiguration configuration)
    {
        Configuration = configuration;
    }

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

    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        if (!options.IsConfigured)
        {
            options.UseSqlServer(Configuration.GetConnectionString("CalendarDatabase"));
        }
    }
}
我认为问题在于为测试创建临时内存数据库所需的行
CalendarDataContext(DbContextOptions)

如何使这个模棱两可的构造函数不那么模棱两可

编辑:添加
startup.cs

public class Startup
{
    public IWebHostEnvironment Environment { get; }

    public Startup(IConfiguration configuration, IWebHostEnvironment environment)
    {
        Environment = environment;
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        if (Environment.IsProduction())
        {
            services.AddDbContext<CalendarDataContext>();
        }
        else if (Environment.IsDevelopment())
        {
            services.AddDbContext<CalendarDataContext, CalendarDataContextSqlite>();
        }
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app,
        IWebHostEnvironment env,
        CalendarDataContext calendarDataContext)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        calendarDataContext.Database.Migrate();
    }
}
公共类启动
{
公共IWebHostEnvironment环境{get;}
公共启动(IConfiguration配置、IWebHostEnvironment环境)
{
环境=环境;
}
//此方法由运行时调用。请使用此方法将服务添加到容器中。
public void配置服务(IServiceCollection服务)
{
if(Environment.IsProduction())
{
services.AddDbContext();
}
else if(Environment.IsDevelopment())
{
services.AddDbContext();
}
}
//此方法由运行时调用。请使用此方法配置HTTP请求管道。
公共无效配置(IApplicationBuilder应用程序,
IWebHostenvironmentEnv,
CalendarDataContext(日历数据上下文)
{
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
calendarDataContext.Database.Migrate();
}
}

首先,将IConfiguration作为本地成员添加到Startup.cs中

IConfiguration Configuration;
public IWebHostEnvironment Environment { get; }

public Startup(IConfiguration configuration, IWebHostEnvironment environment)
{
    Configuration = configuration;
    Environment = environment;
}
然后在启动中注册已配置的CalendarDataContext或CalendarDataContextSqlite

public void ConfigureServices(IServiceCollection services)
{
    if (Environment.IsProduction())
    {
        services.AddDbContext<CalendarDataContext>(options => 
            options.UseSqlServer(
                Configuration.GetConnectionString("CalendarDatabase"));
    }
    else if (Environment.IsDevelopment())
    {
        services.AddDbContext<CalendarDataContext, CalendarDataContextSqlite>(options => {
            var databaseName = Configuration.GetConnectionString("CalendarDatabase");
            var databasePath = PathHelper.DataPath(databaseName);
            options.UseSqlite("Data Source=" + databasePath);
        });
    }
}
public void配置服务(IServiceCollection服务)
{
if(Environment.IsProduction())
{
services.AddDbContext(选项=>
options.UseSqlServer(
GetConnectionString(“日历数据库”);
}
else if(Environment.IsDevelopment())
{
services.AddDbContext(选项=>{
var databaseName=Configuration.GetConnectionString(“CalendarDatabase”);
var databasePath=PathHelper.DataPath(databaseName);
options.UseSqlite(“数据源=“+databasePath”);
});
}
}
然后,CalendarDataContext:

public class CalendarDataContext : DbContext
{
    public DbSet<CalendarEntry> CalendarEntries { get; set; }


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

    protected CalendarDataContext(DbContextOptions options)
        : base(options) { }
}
公共类CalendarDataContext:DbContext { 公共数据库集日历项{get;set;} 公共日历数据上下文(DbContextOptions) :base(选项){} 受保护的CalendarDataContext(DbContextOptions选项) :base(选项){} } 以及CalendarDataContextSqlite:

public class CalendarDataContextSqlite : CalendarDataContext
{
    public CalendarDataContextSqlite(DbContextOptions<CalendarDataContextSqlite> options)
        : base(options) { }
}
公共类CalendarDataContextSqlite:CalendarDataContext { 公共日历DataContextSQLite(DbContextOptions选项) :base(选项){} } 现在,

不需要在上下文类中配置onconfigurang

在生产环境中,无论构造函数在何处请求CalendarDataContext,都将有一个配置好的CalendarDataContext注入

对于developerment,您将配置CalendarDataContextSqlite,以便在构造函数要求CalendarDataContext的任何位置注入


该配置的上下文也将被注入启动。请进行配置,以便您可以迁移数据库。

您正试图将CalendarDataContext作为构造函数参数注入应用程序中的某个位置。可能是注入CalendarService或类似内容?问题是,当DI容器试图提供该CalendarDataContext时,它无法ide要使用的构造函数。应该在启动时配置CalendarDataContext,这样就不需要为(IConfiguration)提供第二个构造函数如果没有配置选项。那么,只有一个构造函数,生活会很好。刚刚注意到问题在于启动的配置方法。也发布StartUp.cs文件。我在问题中添加了我的StartUp.cs刚刚更新了我的答案。这看起来很有希望,但我在
CalendarDataContextSqlite中编译时出错
无法从“Microsoft.EntityFrameworkCore.DbContextOptions”转换为“Microsoft.EntityFrameworkCore.DbContextOptions”
我做错了什么吗?如果我在两个类
CalendarDataContextSqlite
CalendarDataContext
中都保持
IConfiguration配置
,我会在
启动时出错。在数据库迁移时配置
。对于第一个问题,请尝试从构造函数定义中删除GenericType,即仅使用CalendarDataContext(DbContextOptions)和CalendarDataContextSqlite(DbContextOptions).对于第二个问题,我认为没有必要在您的上下文类中保留对IConfiguration的引用。我通过指定的
DbContextOptions
发现了这个问题,并对您的答案进行了相应的编辑。非常感谢!!现在一切正常,迁移也正常。
public class CalendarDataContextSqlite : CalendarDataContext
{
    public CalendarDataContextSqlite(DbContextOptions<CalendarDataContextSqlite> options)
        : base(options) { }
}