Entity framework ASP.NET核心构造函数
我在.NET5中使用ASP.NETCore,最近想从本地开发模式更改为Azure Web生产模式 在本地我使用SQLite,一切正常,在生产上我想使用Azure SQL。 但是,当我想迁移数据库时,会出现一个相当长的异常: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
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) { }
}