Answered by:
Update problem

Question
-
User-1104215994 posted
Hi,
I am trying to update the table. But it does not. How come, I don't understand. There is no error either.
... var gameBankResult = await _unitOfWork.GameBankRepository.GetGamesAsync(g => g.productCode == requestDto.productCode && g.referenceId == Guid.Empty); --> returns 1 result //If we have exact number of games in our database, mark them! if (gameBankResult.Count() != 0 && gameBankResult.Count() >= requestDto.quantity) { for (var index = 0; index < requestDto.quantity; index++) { var item = gameBankResult[index]; item.referenceId = gameRequest.referenceId; item.requestDateTime = DateTime.Now; item.responseDateTime = DateTime.Now; _unitOfWork.GameBankRepository.Update(item); await _unitOfWork.SaveAsync(); ---> does not update the table } //Query GameBank database var gameBankConfirmResult = await _unitOfWork.GameBankRepository.GetGamesAsync(g => g.referenceId == gameRequest.referenceId); ---> returns no result ...
Generic Repo:
public virtual void Update(TEntity entityToUpdate) { dbSet.Attach(entityToUpdate); context.Entry(entityToUpdate).State = EntityState.Modified; }
Unit of work:
public async Task SaveAsync() { await _context.SaveChangesAsync(); }
Wednesday, July 24, 2019 6:52 PM
Answers
-
User-1104215994 posted
I keep the transaction but changed my business logic. Now everything works just I want.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Sunday, July 28, 2019 6:16 PM
All replies
-
User1724605321 posted
Hi cenk1536,
Please provide the entire codes . for example ,Unit of Work Class to help reproduce .
You can also refer to below code sample for Implementing the Repository and Unit of Work Patterns in an ASP.NET MVC Application :
Best Regards,
Nan Yu
Thursday, July 25, 2019 2:05 AM -
User-1104215994 posted
It is due to Transaction scope. If I don't use Transaction scope it is updated immediately but this time how can I rollback if one of the insert/updates fails.
private async Task<HttpResponseMessage> CallGame(RequestDto requestDto) { HttpResponseMessage response = null; using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { //Transform DTO into GameRequest for calling Game Initiate var config = new MapperConfiguration(cfg => { cfg.CreateMap<RequestDto, GameRequest>(); cfg.CreateMap<GameRequest, GameConfirmRequest>(); cfg.CreateMap<GameBank, GameConfirmResponse>(); cfg.CreateMap<GameBankPin, Coupon>(); cfg.CreateMap<GameRequest, GameRequestDto>(); }); var iMapper = config.CreateMapper(); var gameRequest = iMapper.Map<RequestDto, GameRequest>(requestDto); //Unique reference ID gameRequest.referenceId = Guid.NewGuid(); var gameRequestDto = iMapper.Map<GameRequest, GameRequestDto>(gameRequest); //Create signature gameRequest = Utilities.CreateSignature(gameRequestDto, RequestType.Initiate); //Add initiation request into database _unitOfWork.GameRepository.Insert(gameRequest); //Query GameBank database var gameBankResult = await _unitOfWork.GameBankRepository.GetGamesAsync(g => g.productCode == requestDto.productCode && g.referenceId == Guid.Empty); //If we have exact number of games in our database, mark them! if (gameBankResult.Count() != 0 && gameBankResult.Count() >= requestDto.quantity) { for (var index = 0; index < requestDto.quantity; index++) { var item = gameBankResult[index]; item.referenceId = gameRequest.referenceId; item.requestDateTime = DateTime.Now; item.responseDateTime = DateTime.Now; _unitOfWork.GameBankRepository.Update(item); await _unitOfWork.SaveAsync(); } //Query GameBank database var gameBankConfirmResult = await _unitOfWork.GameBankRepository.GetGamesAsync(g => g.referenceId == gameRequest.referenceId); if (gameBankConfirmResult != null) { if (gameBankConfirmResult.Count == 1) { var gameBankConfirmResponse = iMapper.Map<IList<GameBank>, IList<GameConfirmResponse>>(gameBankConfirmResult); gameBankConfirmResponse[0].purchaseStatusDate = DateTime.Now; //Add confirm response into database _unitOfWork.GameConfirmResponseRepository.Insert(gameBankConfirmResponse[0]); var resultResponse = JsonConvert.SerializeObject( gameBankConfirmResponse[0],Formatting.Indented, new JsonSerializerSettings() { ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore }); response = new HttpResponseMessage { StatusCode = System.Net.HttpStatusCode.OK, Content = new StringContent( resultResponse, System.Text.Encoding.UTF8, "application/json"), }; } else if(gameBankConfirmResult.Count > 1) { var gameResult = new GameConfirmResponse { coupons = new List<Coupon>() }; var price = 0.0; var quantity = 0; foreach (var item in gameBankConfirmResult) { price = price + item.unitPrice; quantity = quantity + 1; foreach (var coupons in item.coupons) { var gameCouponResult = new Coupon() { expiryDate = coupons.expiryDate, Pin = coupons.Pin, Serial = coupons.Serial }; //Add coupon values gameResult.coupons.Add(gameCouponResult); } } //Set summed/counted values gameResult.referenceId = gameBankConfirmResult[0].referenceId; gameResult.productCode = gameBankConfirmResult[0].productCode; gameResult.quantity = quantity; gameResult.currency = gameBankConfirmResult[0].currency; gameResult.unitPrice = gameBankConfirmResult[0].unitPrice; gameResult.totalPrice = price; gameResult.productDescription = gameBankConfirmResult[0].productDescription; gameResult.totalPayablePrice = price; //var gameBankConfirmResponse = iMapper.Map<GameBank, GameConfirmResponse>(gameResult); //Add confirm response into database _unitOfWork.GameConfirmResponseRepository.Insert(gameResult); var resultResponse = JsonConvert.SerializeObject( gameResult, Formatting.Indented, new JsonSerializerSettings() { ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore }); response = new HttpResponseMessage { StatusCode = System.Net.HttpStatusCode.OK, Content = new StringContent( resultResponse, System.Text.Encoding.UTF8, "application/json"), }; } } } await _unitOfWork.SaveAsync(); scope.Complete(); } return response; }
Thursday, July 25, 2019 5:37 AM -
User753101303 posted
how can I rollback if one of the insert/updates fails.As I tried to tell earlier this is already what EF 6 and EF Core does out of the box for SaveAsync: https://docs.microsoft.com/en-us/ef/core/saving/transactions
It seems you added your own transaction scope which may "hide" an actual problem you had previously. Instead I would drop using TransactionScope and would fix the actual issue.
Thursday, July 25, 2019 11:44 AM -
User-1104215994 posted
How can I use BeginTransaction with <g class="gr_ gr_4 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar only-ins doubleReplace replaceWithoutSep" id="4" data-gr-id="4">unit</g> of work? Any sample you can show?
using (var transaction = context.Database.BeginTransaction()) { try { context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" }); context.SaveChanges(); context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" }); context.SaveChanges(); var blogs = context.Blogs .OrderBy(b => b.Url) .ToList(); // Commit transaction if all commands succeed, transaction will auto-rollback // when disposed if either commands fails transaction.Commit(); } catch (Exception) { // TODO: Handle failure } }
Thursday, July 25, 2019 12:01 PM -
User753101303 posted
It should be just;
context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" }); context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" }); context.SaveChanges();
ie do all changes to the "repository" and then call SaveChanges once.
When SaveChanges is called, EF inspect all objects attached to the context (directly or even indirectly ie an Order related to OrderDetails for example), and figure out how to update all that in the correct order within a single transaction.
Add for example a 3rd row that would exceed the allowed length for this blog entry or maybe a value that already exists if you have a unique constraint and you'll see that if SaveChanges fails nothing at all is added to the db.
Similarly in the previous code you are calling SaveChanges from within a loop. In most cases you should do all changes and then call this one time at the end to save all changes (or no change at all).
Thursday, July 25, 2019 12:34 PM -
User-474980206 posted
just rollback in the error handler:
using (var transaction = context.Database.BeginTransaction()) { try { context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" }); context.SaveChanges(); context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" }); context.SaveChanges(); var blogs = context.Blogs .OrderBy(b => b.Url) .ToList(); // Commit transaction if all commands succeed, transaction will auto-rollback // when disposed if either commands fails transaction.Commit(); } catch (Exception) { transaction.RollBack(); } }
but as suggested if you use an implicit transaction, it will be faster, as its done in a single batch, rather than as separate batches.
Thursday, July 25, 2019 5:10 PM -
User-1104215994 posted
I keep the transaction but changed my business logic. Now everything works just I want.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Sunday, July 28, 2019 6:16 PM