Base solution for your next web application
Open Closed

Transactions commit within SaveChangesAsync() #1721


User avatar
0
moustafa created

Hello everyone

i have a case that require all changes are saved together if one of them failed then rollback should be executed

the scenario is that i have a patient table that related to User table with a foreign key UserId so when the someone register on the system or from users page i have to create user first then patient the same way when creating a patient from patients pages i have to create user as well everything for now is just fine but i didn't sure if what i'm doing is correct but need to make sure when something happen when saving it should rollback all changes otherwise accept all changes please refer to this post [ <a class="postlink" href="http://stackoverflow.com/questions/815586/entity-framework-using-transactions-or-savechangesfalse-and-acceptallchanges#answer-815660">http://stackoverflow.com/questions/8155 ... wer-815660</a> ])

PatientAppService.cs

private readonly IPatientRepository _patientRepository;
        private readonly IUserAppService _iUserAppService;
        public PatientAppService(IPatientRepository patientRepository, IUserAppService iUserAppService)
        {
            _patientRepository = patientRepository;
            _iUserAppService = iUserAppService;
        }

        [AbpAuthorize(AppPermissions.Pages_Patient_Create)]
        protected virtual async Task CreateRecordAsync(CreateOrEditPatientDto input)
        {
            input.User.IsActive = true;
            input.User.ShouldChangePasswordOnNextLogin = true;
            if (string.IsNullOrEmpty(input.User.EmailAddress))
            {
                input.User.EmailAddress = string.Format("{0}{1}", input.User.UserName, "@hotmail.com");
            }
            CreateOrUpdateUserInput userInput = new CreateOrUpdateUserInput
            {
                AssignedRoleNames = new string[] { "user" },
                SendActivationEmail = true,
                SetRandomPassword = false,
                User = input.User
            };
            await _iUserAppService.CreateOrUpdateUser(userInput);
            var u = await UserManager.FindByNameAsync(input.User.UserName);
            input.Patient.UserId = u.Id;
            var patient = input.Patient.MapTo<Models.Patient.Patient>();
            await _patientRepository.InsertAsync(patient);
        }

4 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    You are doing it right. Please check this document for detailed information. if current unit of work is transactional, all changes in the transaction are rolled back if an exception occurs, even saved changes.

    By the way, instead of calling another appService from PatientAppService, you can convert _iUserAppService to a DomainService and use it in your PatientAppService. <a class="postlink" href="http://aspnetboilerplate.com/Pages/Documents/Domain-Services">http://aspnetboilerplate.com/Pages/Docu ... n-Services</a>

    Calling an AppService from another AppService is not considered as a good practice.

  • User Avatar
    0
    moustafa created

    Hi, i appreciate your help

    1- i think you forgot to write down link of documentation for unit of work transaction

    2- actually i tried for hours to convert _iUserAppService to a DomainService to be used in my PatientAppService but unfortunately i didn't succeeded , i'm so confused about that , i reviewed the link you provided many times but the situations is totally different when it related to UserAppService i follow the steps carefully trying to achieve it till i reach to create UserManager class which should inherit from DomainService class but as you know UserManager Class already exists and already inherits from AbpUserManager<Tenant, Role, User> class , so i tried to create another class and continue but i think i running in wrong way so can you please provide me with snippet code that help me in my case and i think you already have a fresh copy of my project files if you want to do it & test from your side

    regards

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    I'm sorry that I missguided you on this. You can create a domain service called UserService which implements IDomainService and move CreateOrUpdateUser from UserAppService to this new domain service. But if you do that, as I see from the code, you will need to move some other methods.

    Maybe it's better to leave it this way in your case :)

  • User Avatar
    0
    moustafa created

    Hi maybe you right :D but i will try to implement it to understand exactly the idea of domain service thank you