Base solution for your next web application
Open Closed

Duplicate child objects created when references are added #773


User avatar
0
acrigney created

Am getting a strange issue of duplicates of my child objects getting created when I add references to these child objects in a collection. i.e When I add mobile applications to my endUser.MobileApplications I am seeing copies of my MobileApplications being created in the database. As I am only loading the MobileApplication it should not create a copy??

public async Task<long> PostNewEndUserAsync(AddEndUserInput input) { try { Logger.Debug("Adding a new end InviteUser async: " + input.Surname);

            EndUser newEndUser = Mapper.Map&lt;EndUser&gt;(input);

            newEndUser.EndUserSecurityQuestionCode = -1;
            newEndUser.AcceptedTermsAndConditions = input.AcceptedTermsAndConditions;

            if (input.MobileApplications == null)
            {
                // Add the mobile app

                if (String.IsNullOrEmpty(input.ApplicationName))
                {
                    // if none is specified use the DefaultRegistrationApplicationName 
                    input.ApplicationName = ConfigurationFacade.DefaultRegistrationApplicationName;
                }
                List&lt;MobileApplication&gt; mobileApplications = _mobileApplicationRepository.GetAllList(x => x.Name == input.ApplicationName);

                MobileApplication mobileApplication = mobileApplications.FirstOrDefault();

                if (mobileApplication == null)
                {
                    throw new Exception(String.Format("Mobile application {0} was not found to register the end user for.", input.ApplicationName));
                }

                newEndUser.MobileApplications.Add(_mobileApplicationRepository.Load(mobileApplication.Id));
            }
            else
            {
               **foreach (MobileApplicationDto mobileApplication in input.MobileApplications)
                {
                    newEndUser.MobileApplications.Add(_mobileApplicationRepository.Load(mobileApplication.Id));
                }**
            }
            long id = await _endUserRepository.InsertAndGetIdAsync(newEndUser);
            return (id);
        }
        catch (Exception ex)
        {
            string msg = ex.GetBaseException().Message;
            UserFriendlyException userFriendlyException = new UserFriendlyException(msg);
            throw userFriendlyException;
        }            
    }

2 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    Probably, AutoMapper creates newEndUser.MobileApplications collection from input.MobileApplications in this mapping line:

    Mapper.Map<EndUser>(input);
    
  • User Avatar
    0
    acrigney created

    Awesome yes thanks mate Automapper is the problem! I am using ignore for the mobile applications as I thought that was safer coding,

    However even when I change automapper to map from the input, which has the correct loaded values (not new values), it still wants to add them. So I just put a work around for now till I can find whats wrong to clear the collection before I add the specified child values in.

    Mapper.CreateMap<AddEndUserInput, EndUser>() .ForMember(x => x.Id, option => option.Ignore()) .ForMember(x => x.Patients, option => option.Ignore()) .ForMember(x => x.MobileApplications, option => option.Ignore()); //.ForMember(dest => dest.MobileApplications, opt => opt.MapFrom(src => src.MobileApplications));

    public async Task<long> PostNewEndUserAsync(AddEndUserInput input) { try { Logger.Debug("Adding a new end InviteUser async: " + input.Surname);

                EndUser newEndUser = Mapper.Map&lt;EndUser&gt;(input);
    
                newEndUser.EndUserSecurityQuestionCode = -1;
                newEndUser.AcceptedTermsAndConditions = input.AcceptedTermsAndConditions;
    
                //// dummy code to get the mobile apps
                //    GetApplicationsInput getApplicationsInput = new GetApplicationsInput() { Name = null };
                //    var result = await _mobileApplicationRepository.GetMobileApplicationAsync&lt;MobileApplicationDto&gt;(getApplicationsInput);
    
                //    //var mobileApp = result.MobileApplications[0];
    
                //    input.MobileApplications = result.MobileApplications;
    
                if (input.MobileApplications == null)
                {
                    // Add the mobile app
    
                    if (String.IsNullOrEmpty(input.ApplicationName))
                    {
                        // if none is specified use the DefaultRegistrationApplicationName 
                        input.ApplicationName = ConfigurationFacade.DefaultRegistrationApplicationName;
                    }
                    List&lt;MobileApplication&gt; mobileApplications = _mobileApplicationRepository.GetAllList(x => x.Name == input.ApplicationName);
    
                    MobileApplication mobileApplication = mobileApplications.FirstOrDefault();
    
                    if (mobileApplication == null)
                    {
                        throw new Exception(String.Format("Mobile application {0} was not found to register the end user for.", input.ApplicationName));
                    }
    
                    newEndUser.MobileApplications.Add(_mobileApplicationRepository.Load(mobileApplication.Id));
                }
                else
                {
                    **if (newEndUser.MobileApplications != null)
                    {
                        newEndUser.MobileApplications.Clear();
                    }**
                    foreach (MobileApplicationDto mobileApplication in input.MobileApplications)
                    {
                        newEndUser.MobileApplications.Add(_mobileApplicationRepository.Load(mobileApplication.Id));
                    }
                }
                long id = await _endUserRepository.InsertAndGetIdAsync(newEndUser);
                return (id);
            }
            catch (Exception ex)
            {
                string msg = ex.GetBaseException().Message;
                UserFriendlyException userFriendlyException = new UserFriendlyException(msg);
                throw userFriendlyException;
            }            
        }