【发布时间】:2019-08-01 16:52:40
【问题描述】:
我已经使用(我认为是正确的)设置了自己的上下文:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<JobTrackingContext>(options => options.UseNpgsql(connection));
services.AddScoped<IJobRepository, JobRepository>();
}
然后我定义我的JobTrackingContext如下:
public JobTrackingContext(DbContextOptions<JobTrackingContext> options)
: base(options)
{
public DbSet<Job> Jobs { get; set; }
}
现在我可以定义一个存储库来实际创建/编辑/删除作业:
public class JobRepository : GenericRepository<Job, long>, IJobRepository
{
private Job currentJob;
public JobRepository(JobTrackingContext jobTrackingContext, JobTrackingSettings settings)
: base(jobTrackingContext)
{
_settings = settings;
}
public async Task StartSync(JobType jobType, JobTriggerType jobTriggerType)
{
var tempJob = new Job(jobType, jobTriggerType);
await _dbContext.Jobs.AddAsync(tempJob);
await _dbContext.SaveChangesAsync();
}
}
所有这些代码都通过对该 API 的 Post-request 实例化:
public async void Post()
{
_logger.LogDebug("Going to start account sync");
await _jobRepository.StartSync(JobType.ZRequestSync, JobTriggerType.Scheduled);
try
{
await _sync.StartAsync();
await _jobRepository.ChangeSyncStatus(JobStatusType.Finished);
}
catch (Exception e)
{
_logger.LogError(e, "Error occured during sync :(");
await _jobRepository.ChangeSyncStatus(JobStatusType.Failed);
}
}
然而,当我这样做时,我得到一个异常消息Reset() called on connector with state Connecting。我不明白这是从哪里来的。
当我不使用注入版本,而是这样做时:
using (var c = new JobTrackingContext())
{
var job = new Job(jobType, jobTriggerType)
await c.Jobs.AddAsync(job);
await c.SaveChangesAsync();
}
似乎一切正常。似乎上下文被处理得太早了。但是我怎样才能防止这种情况和/或我错过了什么?
完整的堆栈跟踪:
System.ObjectDisposedException
HResult=0x80131622
Message=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.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
at Microsoft.EntityFrameworkCore.DbContext.<SaveChangesAsync>d__52.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()
at ZShared.JobRepository.<StartSync>d__4.MoveNext() in C:\Users\richa\Documents\Codes\Company\Product\Shared\Folder\JobRepository.cs:line 38
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at ZAccountSyncService.AccountSyncController.<Post>d__4.MoveNext() in C:\Users\richa\Documents\Code\Company\Product\SubProduct\AccountSyncController.cs:line 32
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
【问题讨论】:
-
_dbContext在您的JobRepository代码示例中来自哪里?似乎您在示例中有整个类,但既没有构造函数,也没有名为_dbContext... -
保存在超类中,我现在做的更清楚了
-
你试过
.AddDbContext而不是.AddDbContextPool吗?它有效吗?你的生命周期是多少?它是一个什么样的应用程序? ASP.NET (Core) 还是其他的?此外:您的最后一个代码示例可能会起作用,因为它在调用.AddAsync方法时缺少await。在那里添加被遗忘的await是否有效? -
是的,我尝试将其更改为
.AddDbContext,但遗憾的是这并不能解决问题。生命周期范围是什么?我的JobRepository是作用域的,就像我的大多数课程一样。JobTrackingContext也是如此。这是一个 ASP.NETCORE 应用程序,是的,添加await不会破坏我的其他示例。 -
("scoped" 意味着您在一个范围内为每个范围内的服务获取一个实例。范围多长时间取决于您 - 在 ASP.NET Core 中,默认情况下会为每个 Web 请求创建一个范围。 ) 你什么时候得到异常?打电话时
SaveChangesAsync?你能提供整个堆栈跟踪吗?
标签: asp.net entity-framework dependency-injection .net-core