#c# #asp.net-core #asynchronous
Вопрос:
В моем контроллере API у меня есть такой код:
[HttpPost]
public async Task<ActionResult<TransactionDto>> CreateNewTrasaction(TransactionDto accountCreateDto)
{
var commandModel = _mapper.Map<TransactionHistory>(accountCreateDto);
_transactionRepository.CreateTransaction(commandModel);
var accountReadDto = _mapper.Map<AccountReadDto>(commandModel);
return Ok();
}
И внутри transactionRepository
класса я сделал следующее:
private readonly TransactionContext _transContext;
public TransactionRp(TransactionContext tContext)
{
_transContext = tContext;
}
public async Task CreateTransaction(TransactionHistory transaction)
{
using(IDbContextTransaction transactionContext = _transContext.Database.BeginTransaction())
{
try
{
transaction.CreatedDate = DateTime.UtcNow;
_transContext.TransactionHistories.Add(transaction);
await _transContext.SaveChangesAsync();
var senderAccount = _transContext.Accounts.FirstOrDefault(x => x.AccountNo == transaction.AccountNo);
var receiverAccount = _transContext.Accounts.FirstOrDefault(x => x.AccountNo == transaction.ReceiverAccount);
senderAccount.Amount = senderAccount.Amount - transaction.Amount;
receiverAccount.Amount = senderAccount.Amount transaction.Amount;
_transContext.Accounts.Update(receiverAccount);
_transContext.Accounts.Update(receiverAccount);
}
catch (Exception ex)
{
throw;
}
}
}
Но когда я запускаю код, я получаю ошибку в этой строке
await _transContext.SaveChangesAsync();
И ошибка в том, что:
Не удается получить доступ к удаленному экземпляру контекста.
Распространенной причиной этой ошибки является удаление экземпляра контекста, который был устранен в результате внедрения зависимостей, а затем последующая попытка использовать тот же экземпляр контекста в другом месте приложения.
Это может произойти, если вы вызываете «Dispose» для экземпляра контекста или заключаете его в инструкцию using. Если вы используете внедрение зависимостей, вы должны позволить контейнеру внедрения зависимостей позаботиться об удалении экземпляров контекста.Имя объекта: ‘Транзакционный контекст’
Обновленный
Вот как я меняю контекст внутри ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<TransactionContext>(opt => opt.UseSqlServer
(Configuration.GetConnectionString("BankConnection"))
);
}
Комментарии:
1. Вы не показываете, как управляется _transContext. Это ДИ?
2. @DavidBrowne-Обновленный код Microsoft, я новичок в .net core. Я думаю, что это то, о чем ты спрашивал
3. Почему вы хотите использовать TransactionScope в первую очередь? Если вы используете EF Core или аналогичную ORM, изменения кэшируются и сохраняются в базе данных только при
SaveChanges
вызове в самом конце запроса. Вам не нужны явные транзакции, сам DbContext предоставляет вам семантику транзакций. Если вы позвонитеSaveChanges
несколько раз … не звоните. По крайней мере, не без очень серьезной причины4. И если вы хотите распределенные транзакции, они не поддерживаются . Чистое ядро. И, кстати, вы не ждете выполнения задачи, а это значит, что нет никакой гарантии, когда операция будет фактически обработана. (вероятно, это происходит после завершения первоначального вызова, поэтому вы получаете ошибку удаления.)
Ответ №1:
Похоже, проблема в контроллере. используйте await
с async
помощью метода. async
ключевое слово используется для того, чтобы сделать функцию асинхронной. await
Ключевое слово попросит выполнение подождать, пока не будет выполнена определенная задача. Подробнее
[HttpPost]
public async Task<ActionResult<TransactionCreateDto>> CreateNewTrasaction(TransactionCreateDto accountCreateDto)
{
var commandModel = _mapper.Map<TransactionHistory>(accountCreateDto);
await _trasactionRepository.CreateTransaction(commandModel);
var accountReadDto = _mapper.Map<AccountReadDto>(commandModel);
return Ok();
}