Существует проблема с асинхронным c, выполняющим запрос к веб-API с использованием структуры объекта. Общий вид таков, что запрос отправляется в API, а ActionFilter перехватывает запрос функции контроллера, отправляет клиенту статус ok с ключом ответа, выполняет запрос asyn c и после отправки данных SignalR. ActionFilter запускается в асинхронном режиме c выполняется следующим образом:
HostingEnvironment.QueueBackgroundWorkItem(async (ct) =>
{
var response = await actionContext.ActionDescriptor.ExecuteAsync(actionContext.ControllerContext,
actionContext.ActionArguments, ct);
var data = new JavaScriptSerializer().Serialize(response);
await connectionContext.Connection.Send(connectionId, $"{requestKey};{data}");
});
Контроллер:
[HttpPost]
[Route("")]
public ICollection<TradeAccountModel> GetAll()
{
using (var ls = _lifetimeScope.BeginLifetimeScope())
{
return _tradeAccountService.GetAll();
}
}
Служба:
public ICollection<TradeAccountModel> GetAll()
{
using (_tradeAccountRepository.BeginTransaction())
{
return _tradeAccountRepository.Get().Select(acc => acc.ToModel());
}
}
Репозиторий использует шаблон UOW. И когда репозиторий пытается получить данные из БД, возникает ошибка: System.InvalidOperationException: операция не может быть завершена, поскольку удален DbContext.
TDataRepository содержит общие операций и расширений BaseDataRespository, таких как GetById и т. д.
public interface ITradeRepository: ITDataRepository<TradeAccount>
{
}
internal class TradeRepository : T1DataRepository<TradeAccount>,
ITradeRepository
{
}
IEnumerable<TEntity> ITDataRepository<TEntity>.Get()
{
return base.Get<TEntity>();
}
BaseDataRespository имеет метод BeginTransaction
public IDisposable BeginTransaction()
{
if (_scope == null)
{
_scope = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions()
{
IsolationLevel = IsolationLevel.ReadCommitted,
Timeout = TimeSpan.FromSeconds(300)
},
TransactionScopeAsyncFlowOption.Enabled);
}
return _scope;
}
Создание контекста с помощью BaseDataRespository
private TransactionScope _scope;
private readonly Lazy<DataContext> _contextFactory;
private DataContext Context => _contextFactory.Value;
public BaseDataRepository()
{
_contextFactory = new Lazy<DataContext>(()=>
{
var ctx = CreateContext();
ctx.FireBuild += Build;
return ctx;
});
}