我正在编写一个ASP.NET Core Web应用程序,需要从数据库中获取一些表的所有数据,以便稍后将其组织成可读格式进行分析。
我的问题是,这些数据可能非常庞大,为了提高性能,我决定同时获取这些数据而不是逐个表获取。
我的问题是,我不太理解如何通过继承依赖注入来实现这一点,因为为了能够进行并行工作,我需要为每个并行工作实例化
以下代码会产生此异常:
ASP.NET Core项目:
Startup.cs:
我的问题是,这些数据可能非常庞大,为了提高性能,我决定同时获取这些数据而不是逐个表获取。
我的问题是,我不太理解如何通过继承依赖注入来实现这一点,因为为了能够进行并行工作,我需要为每个并行工作实例化
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();
}
}
await
比使用WaitAll
/WhenAll
更好吗?WhenAny
呢?另外,使用单个DbContext
是否会导致其跟踪或缓存以某种方式被破坏,并影响稍后调用SaveChanges
的上游调用者?如果是这样,我会说警告是正确的,因为默认情况下DbContext的作用域限制在请求范围内,而您的方法进行并行查询不能保证另一个方法将如何处理相同的DbContext
实例。 - xr280xr