public virtual async Task CreateAsync(User user)
        {
            ThrowIfDisposed();
            Guard.ArgumentNotNull(user, nameof(user));

            _dbContext.Add(user);
            await _dbContext
                .SaveChangesAsync(_cancellationToken)
                .ConfigureAwait(false);
        }
        public async Task UpdateAsync(User user)
        {
            ThrowIfDisposed();
            Guard.ArgumentNotNull(user, nameof(user));

            _dbContext.Attach(user);
            user.ConcurrencyStamp = Guid.NewGuid().ToString();
            _dbContext.Update(user);
            await _dbContext
                .SaveChangesAsync(_cancellationToken)
                .ConfigureAwait(false);
        }
        private async Task CreateOrUpdateUserAsync(AuthenticationTicket authenticationTicket, UserManager userManager, Tenant tenant)
        {
            Guard.ArgumentNotNull(authenticationTicket, nameof(authenticationTicket));
            Guard.ArgumentNotNull(userManager, nameof(userManager));
            Guard.ArgumentNotNull(tenant, nameof(tenant));

            var principal = authenticationTicket.Principal;
            string objectIdentifier = principal.GetObjectIdentifierValue();
            string displayName = principal.GetDisplayNameValue();
            string email = principal.GetEmailValue();

            var user = await userManager.FindByObjectIdentifier(objectIdentifier)
                .ConfigureAwait(false);
            if (user == null)
            {
                // The user isn't in our database, so add them.
                user = new User
                {
                    Created = DateTimeOffset.UtcNow,
                    ObjectId = objectIdentifier,
                    TenantId = tenant.Id,
                    DisplayName = displayName,
                    Email = email
                };

                await userManager.CreateAsync(user)
                    .ConfigureAwait(false);
            }
            else
            {
                // Since we aren't the system of record, we need to attempt to keep our display values in sync with the user store.
                // We'll do a simple form of it here.
                bool shouldSaveUser = false;
                if (!user.DisplayName.Equals(displayName, StringComparison.OrdinalIgnoreCase))
                {
                    user.DisplayName = displayName;
                    shouldSaveUser = true;
                }

                // Do a case insensitive comparison for email matching
                if (!user.Email.Equals(email, StringComparison.OrdinalIgnoreCase))
                {
                    user.Email = email;
                    shouldSaveUser = true;
                }

                if (shouldSaveUser)
                {
                    await userManager
                        .UpdateAsync(user)
                        .ConfigureAwait(false);
                }
            }

            // Add in the survey user id claim.
            principal.Identities.First().AddClaim(new Claim(SurveyClaimTypes.SurveyUserIdClaimType, user.Id.ToString()));
            // Add in the user's tenant id claim.
            principal.Identities.First().AddClaim(new Claim(SurveyClaimTypes.SurveyTenantIdClaimType, user.TenantId.ToString()));
        }