【发布时间】:2019-03-22 05:30:34
【问题描述】:
我正在编写一个 ASP.NET Core Web 应用程序,该应用程序需要数据库中某些表中的所有数据,以便稍后将其组织成可读格式以进行某些分析。
我的问题是这些数据可能非常庞大,因此为了提高性能,我决定并行获取这些数据,而不是一次获取一个表。
我的问题是我不太明白如何通过继承依赖注入来实现这一点,因为为了能够进行并行工作,我需要为每个并行工作实例化 DbContext。
下面的代码会产生这个异常:
---> (Inner Exception #6) System.ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'MyDbContext'.
at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.get_ChangeTracker()
ASP.NET Core 项目:
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddDistributedMemoryCache();
services.AddDbContext<AmsdbaContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("ConnectionString"))
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking));
services.AddSession(options =>
{
options.Cookie.HttpOnly = true;
});
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
if (HostingEnvironment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
loggerFactory.AddLog4Net();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSession();
app.UseMvc();
}
控制器的动作方法:
[HttpPost("[controller]/[action]")]
public ActionResult GenerateAllData()
{
List<CardData> cardsData;
using (var scope = _serviceScopeFactory.CreateScope())
using (var dataFetcher = new DataFetcher(scope))
{
cardsData = dataFetcher.GetAllData(); // Calling the method that invokes the method 'InitializeData' from below code
}
return something...;
}
.NET Core 库项目:
DataFetcher的InitializeData——根据一些不相关的参数获取所有表记录:
private void InitializeData()
{
var tbl1task = GetTbl1FromDatabaseTask();
var tbl2task = GetTbl2FromDatabaseTask();
var tbl3task = GetTbl3FromDatabaseTask();
var tasks = new List<Task>
{
tbl1task,
tbl2task,
tbl3task,
};
Task.WaitAll(tasks.ToArray());
Tbl1 = tbl1task.Result;
Tbl2 = tbl2task.Result;
Tbl3 = tbl3task.Result;
}
DataFetcher 的示例任务:
private async Task<List<SomeData>> GetTbl1FromDatabaseTask()
{
using (var amsdbaContext = _serviceScope.ServiceProvider.GetRequiredService<AmsdbaContext>())
{
amsdbaContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
return await amsdbaContext.StagingRule.Where(x => x.SectionId == _sectionId).ToListAsync();
}
}
【问题讨论】:
标签: c# asp.net-core dependency-injection entity-framework-core