protected bool Equals(InternationalAffiliation other)
 {
     return  From.Equals(other.From) &&
             To.Equals(other.To) &&
             OnGoing.Equals(other.OnGoing) &&
             string.Equals(Institution, other.Institution) &&
             Locations.OrderBy(a => a.PlaceId).SequenceEqual(other.Locations.OrderBy(b => b.PlaceId)) &&
             string.Equals(Position, other.Position);
 }
        public void Handle(UpdateInternationalAffiliation command)
        {
            if (command == null)
            {
                throw new ArgumentNullException("command");
            }

            /* Retrieve the expertise to update. */
            var target = _entities.Get <InternationalAffiliation>().SingleOrDefault(a => a.RevisionId == command.Id);

            if (target == null)
            {
                string message = String.Format("Affiliation Id {0} not found.", command.Id);
                throw new Exception(message);
            }

            var updated = new InternationalAffiliation
            {
                From        = command.From,
                To          = command.To,
                OnGoing     = command.OnGoing,
                Institution = command.Institution,
                Position    = command.Position,
                Locations   = command.Locations
            };

            /* If target fields equal new field values, we do not proceed. */
            if (target.Equals(updated))
            {
                return;
            }

            /* Run through all new locations and attempt to find same in target.  If not found, create.*/
            foreach (var location in command.Locations.ToList())
            {
                var targetLocation = target.Locations.SingleOrDefault(x => x.PlaceId == location.PlaceId);
                if (targetLocation == null)
                {
                    var createAffiliationLocation = new CreateInternationalAffiliationLocation(
                        command.Principal, target.RevisionId, location.PlaceId)
                    {
                        NoCommit = true
                    };

                    _createAffiliationLocation.Handle(createAffiliationLocation);
                }
            }

            /* Delete activity locations. Run through the targets list of locations and try to find
             *  a matching one in the updated list.  If not found, it must have been deleted. */
            foreach (var location in target.Locations.ToList())
            {
                var updateLocation = command.Locations.SingleOrDefault(x => x.PlaceId == location.PlaceId);
                if (updateLocation == null)
                {
                    var deleteAffiliationLocationCommand = new DeleteInternationalAffiliationLocation(
                        command.Principal, location.RevisionId)
                    {
                        NoCommit = true
                    };

                    _deleteAffiliationLocation.Handle(deleteAffiliationLocationCommand);
                }
            }

            /* Update fields */
            target.From               = command.From;
            target.To                 = command.To;
            target.OnGoing            = command.OnGoing;
            target.Institution        = command.Institution;
            target.Position           = command.Position;
            target.Locations          = command.Locations;
            target.UpdatedOnUtc       = command.UpdatedOn.ToUniversalTime();
            target.UpdatedByPrincipal = command.Principal.Identity.Name;

            _entities.Update(target);

            if (!command.NoCommit)
            {
                _unitOfWork.SaveChanges();
            }
        }