The changes to the database were committed successfully, but an error occurred while updating the object contextRSS

raysefo

Well-known member
Joined
Feb 22, 2019
Messages
361
Programming Experience
10+
Hi,

I have a asp.net web API. I am using EF 6 code first approach. I am getting this error only when I load testing my web API with Jmeter. How can I fix this?

C#:
The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: Saving or accepting changes failed because more than one entity of type 'BusinessEntity.GameResponse' have the same primary key value. Ensure that explicitly set primary key values are unique. Ensure that database-generated primary keys are configured correctly in the database and in the Entity Framework model. Use the Entity Designer for Database First/Model First configuration. Use the 'HasDatabaseGeneratedOption" fluent API or 'DatabaseGeneratedAttribute' for Code First configuration

Here is my GameResponse:

C#:
using System;

namespace BusinessEntity
{
    public class GameResponse
    {
        public int Id { get; set; }
        public string referenceId { get; set; }
        public string productCode { get; set; }
        public int quantity { get; set; }
        public string version { get; set; }
        public string signature { get; set; }
        public string ApplicationCode { get; set; }
        public string validatedToken { get; set; }
        public DateTime? responseDateTime { get; set; } = DateTime.Now;
        public string initiationResultCode { get; set; }
        public string companyToken { get; set; }
        public string estimateUnitPrice { get; set; }
        public string currency { get; set; }
    }
}

Here is the method I am load testing:

C#:
private async Task<HttpResponseMessage> CallRazerService(RequestDto requestDto)
        {
            HttpResponseMessage response = null;

            using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    //Transform DTO into GameRequest for calling Razer Initiate
                    var config = new MapperConfiguration(cfg =>
                    {
                        cfg.CreateMap<RequestDto, GameRequest>();
                        cfg.CreateMap<GameRequest, GameConfirmRequest>();
                        cfg.CreateMap<GameConfirmResponse, GameConfirmResponseDto>();
                        cfg.CreateMap<Coupon, CouponDto>();
                    });
                    var iMapper = config.CreateMapper();
                    var gameRequest = iMapper.Map<RequestDto, GameRequest>(requestDto);
                    //Unique reference ID
                    gameRequest.referenceId = Guid.NewGuid().ToString();

                    //Create signature
                    gameRequest = Utilities.CreateSignature(gameRequest, RequestType.Initiate);

                    //Add initiation request into database
                    _unitOfWork.GameRepository.Insert(gameRequest);
                    

                    #region Call Razer initiate/confirm

                    //Call Razer for initiation
                    response = await Utilities.CallRazer(gameRequest, "purchaseinitiation");

                    //Read response
                    var htmlResponse = await response.Content.ReadAsStringAsync();
                    var gameResponse = JsonConvert.DeserializeObject<GameResponse>(htmlResponse);

                    //Adding initiation response into database
                    _unitOfWork.GameResponseRepository.Insert(gameResponse);
                    

                    if (gameResponse.initiationResultCode == "00")
                    {
                        gameRequest.validatedToken = gameResponse.validatedToken;
                        //Create signature
                        var gameConfirmRequest = Utilities.CreateSignature(gameRequest, RequestType.Confirm);

                        //Transform DTO into GameRequest for calling Razer Initiate
                        var gameConfirmRequests = iMapper.Map<GameRequest, GameConfirmRequest>(gameConfirmRequest);

                        //Add confirm request into database
                        _unitOfWork.GameConfirmRequestRepository.Insert(gameConfirmRequests);
                        

                        //Call Razer for confirm
                        response = await Utilities.CallRazer(gameRequest, "purchaseconfirmation");

                        //Read response
                        htmlResponse = await response.Content.ReadAsStringAsync();
                        var gameConfirmResponse = JsonConvert.DeserializeObject<GameConfirmResponse>(htmlResponse);

                        //Add confirm response into database
                        _unitOfWork.GameConfirmResponseRepository.Insert(gameConfirmResponse);
                    }
                }
                catch (Exception e)
                {
                    throw e;
                }

                #endregion

                await _unitOfWork.SaveAsync();
                scope.Complete();
            }

            return response;
        }
 
I have good news for you guys. I made a load test with 1000 users and 10 seconds ramp-up time, there were no errors :) I just removed the transaction scope from the code.
 
Back
Top Bottom