private async Task <OrganizationMember> FindExistingMemberAsync(
     Organization organization,
     ApplicationUser user,
     OrganizationMemberRetrievalOptions options = null)
 {
     return(await _context.OrganizationMembers
            .AsNoTracking()
            .UseOptions(options ?? new OrganizationMemberRetrievalOptions())
            .FirstOrDefaultAsync(m => m.OrganizationId == organization.OrganizationId &&
                                 m.UserId == user.Id));
 }
        public static IQueryable <OrganizationMember> UseOptions(
            this IQueryable <OrganizationMember> query,
            OrganizationMemberRetrievalOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (options.LoadRoles)
            {
                query = query.Include(m => m.Roles);
            }

            return(query);
        }
        public async Task <OrganizationMember> AddToOrganizationAsync(
            ApplicationUser user,
            Organization organization = null,
            OrganizationMemberRetrievalOptions options = null)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            organization ??= await _currentOrganizationAccessorService
            .RequireCurrentOrganizationAsync();

            await CheckOrganizationAdminAccessAsync(organization);

            var member = await FindExistingMemberAsync(organization, user,
                                                       options ?? new OrganizationMemberRetrievalOptions());

            if (member == null)
            {
                try
                {
                    member = new OrganizationMember
                    {
                        OrganizationId = organization.OrganizationId,
                        UserId         = user.Id
                    };
                    await _context.OrganizationMembers.AddAsync(member);

                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateException e) when(e.IsUniqueKeyViolation())
                {
                    _logger.LogWarning(e, e.Message);
                    if (member != null)
                    {
                        _context.OrganizationMembers.Remove(member);
                    }
                    return(await FindExistingMemberAsync(organization, user, options));
                }
            }

            return(member);
        }
        public async Task <OrganizationMember> FindOrganizationMemberAsync(
            ApplicationUser user,
            Organization organization = null,
            OrganizationMemberRetrievalOptions options = null)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            organization ??= await _currentOrganizationAccessorService
            .GetCurrentOrganizationAsync();

            if (organization == null)
            {
                return(null);
            }

            return(await FindExistingMemberAsync(organization, user, options));
        }