- What is your product version?
- 10.0.3
- What is your product type (Angular or MVC)?
- MVC
- What is product framework type (.net framework or .net core)?
- .net core
Hi all, I'm trying to access TenantManager in BackgroundJob. But i'm getting is disposed error.
System.ObjectDisposedException Cannot access a disposed context instance. A common cause of this error is disposing a context instance 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 instance, or wrapping it 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: 'CustomerHubDbContext'.
System.ObjectDisposedException: Cannot access a disposed context instance. A common cause of this error is disposing a context instance 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 instance, or wrapping it 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: 'CustomerHubDbContext'. at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed() at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() at Microsoft.EntityFrameworkCore.DbContext.get_Model() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.get_EntityType() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.get_EntityQueryable() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.System.Collections.Generic.IEnumerable<TEntity>.GetEnumerator() at CustomerHub.Jobs.SyncBusinessPartners.Execute(Int32 x) in C:_GIT\SyncBusinessPartners.cs:line 42
Below the code of SyncBusinessPartners Job (highlighted the row in error - line42)
public class SyncBusinessPartners : BackgroundJob<int>, ITransientDependency
{
private readonly TenantManager _tenantManager;
private readonly IAbpSession _abpSession;
private readonly UserManager _userManager;
private readonly ILogger<SyncBusinessPartners> _logger;
public SyncBusinessPartners(
TenantManager tenantManager,
IAbpSession abpSession,
UserManager userManager,
ILogger<SyncBusinessPartners> logger
)
{
_tenantManager = tenantManager;
_abpSession = abpSession;
_userManager = userManager;
_logger = logger;
LocalizationSourceName = CustomerHubConsts.LocalizationSourceName;
}
public override void Execute(int x)
{
_logger.LogInformation(L("JobExecutionStarted", args: $"{nameof(SyncBusinessPartners)}"));
**foreach (var t in _tenantManager.Tenants)**
{
var admin = _userManager.FindByNameAsync("admin").Result;
}
_logger.LogInformation(L("JobExecutionFinished", args: nameof(DocumentDto)));
}
}
I've tried to use UnitOfWork attribute on my method Execute. But when i do this, all the information to be synced in bulk and not iteration by iteration.
Thanks in advance!
3 Answer(s)
-
0
Can you try injecting
IUnitOfWorkManager
and try using like: <br>public override void Execute(int x) { _logger.LogInformation(L("JobExecutionStarted", args: $"{nameof(SyncBusinessPartners)}")); using(var unitOfWork = _unitOfWorkManager.Begin()) { foreach (var t in _tenantManager.Tenants) { var admin = _userManager.FindByNameAsync("admin").Result; } _logger.LogInformation(L("JobExecutionFinished", args: nameof(DocumentDto))); unitOfWork.Complete(); } }
Or put
using(var unitOfWork = _unitOfWorkManager.Begin())
inside foreach if you want separate UoW for each userManager operation. -
0
Hi gterdem.
I've already tried to use UnitOfWorks, but with no luck. Some examples below.
public override void Execute(int x) { _logger.LogInformation(string.Format("Starting {0}...", nameof(T))); using (var unitOfWork = _unitOfWorkManager.Begin()) foreach (var t in _tenantManager.Tenants) using (var tUnitOfWork = _unitOfWorkManager.Begin()) { using (_unitOfWorkManager.Current.SetTenantId(t.Id)) { var list = _externalWSClient.GetList<ItemDto>(); foreach (var i in list) { _localRepoService.ImportItemAsync(i).Result; //Commit Here } } tUnitOfWork.Complete(); } _logger.LogInformation(string.Format("Finished {0}...", nameof(T))); }
[UnitOfWork] public override void Execute(int x) { _logger.LogInformation(string.Format("Starting {0}...", nameof(T))); using (_unitOfWorkManager.Current.SetTenantId(t.Id)) { var list = _externalWSClient.GetList<ItemDto>(); foreach (var i in list) { _localRepoService.ImportItemAsync(i).Result; //Commit Here } } _logger.LogInformation(string.Format("Finished {0}...", nameof(T))); }
With both, TenantManager works. It retrieves all the tenants and i can iterate over them. What i'm missing right now, is the capability of saving on each item import. The commit only occurs when the job finishes, right after the Finished log.
-
0
Hi @rcasaca
You can call
_unitOfWorkManager.Current.SaveChanges();
when you want to insert the records.