Как выполнить сложный поисковый запрос linq для нескольких таблиц? - PullRequest
0 голосов
/ 26 апреля 2020

Я хочу, чтобы мой пользователь мог искать пользователей, принадлежащих к таблице ConnectorLocation (ApplicationUserId, SiteId), имеющих конкретно заданный SiteId.

У последних пользователей поиск выполняется по любой из следующих данных:

-username найдено в таблице ApplicationUser

-Age как DOB найдено в таблице ApplicationUser

-emailAddress найдено в таблице ApplicationUser

-religionName найдено в таблице Religion где ReligionId - это внешний ключ в таблице ApplicationUser

-interestName, найденный в таблице категорий, где InterestId - это внешний ключ в таблице UserInterests (InterestId, ApplicationUserId)

-locationName, найденный в таблице сайтов, где LocationId - это внешний ключ в таблице ApplicationUser

Поиск основан на концепции «% Like%», он не обязательно совпадает.

Я хочу использовать операции Skip & Take linq, так как я хочу лениво загрузить результаты поискового запроса на основе заданного номера страницы.

Из всех запросов я просто хочу имя пользователя и profilePicture получающихся пользователей.

Метод имеет следующую структуру: searchConnectors (string query, int pageNumber, int SiteId)

У меня проблема с эффективным извлечением результатов без больших накладных расходов, потому что данные несколько большие.

Любая помощь приветствуется !!

Это то, что я пытался, я знаю, что это не очень эффективно.

    [HttpGet]
    [Route("searchConnectors/{query}/{siteId}/{pageNumber}")]
    public string searchConnectors(string query, int siteId,int pageNumber)

    {

        int skip = 10 * (pageNumber - 1);

        var ids = _dbContext.ConnectorLocations.Where(c => c.SiteId == siteId).Select(c=>c.ApplicationUserId).ToList();



        var find = _dbContext.Religions.Where(c => c.Name.ToLower().Contains(query.ToLower())).Select(c=>c.Id).ToList();
        List<string> religionUsers = new List<string>();
        if (find.Any()) {

           var findUsers = _dbContext.ApplicationUsers.Where(c => find.Contains((int)c.ReligionId) && ids.Contains(c.Id)).Select(p => p.Id).ToList();
            if (findUsers.Any())
            {
              // var queryReligion= _dbContext.ApplicationUsers.Where(c => c.ReligionId == id).Select(p=>p.Id).ToList();
                religionUsers.AddRange(findUsers);
            } 
        }


        var isNumeric = int.TryParse(query, out _);
        List<string> ageUsers = new List<string>();
        int now = int.Parse(DateTime.Now.ToString("yyyyMMdd"));
        if (isNumeric)
        {
            var checkDOB = _dbContext.ApplicationUsers.AsEnumerable().Where(x => ids.Contains(x.Id) &&((now-int.Parse(x.DateOfBirth.ToString("yyyyMMdd")))/10000)==int.Parse(query)).Select(x=>x.Id).ToList();
            if(!checkDOB.Any())
            {
                isNumeric = false;
            }
            else
            {
                ageUsers.AddRange(checkDOB);
            }
        }

        List<string> locationUsers = new List<string>();
        var findLocation = _dbContext.Sites.Where(c => c.Name.ToLower().Contains(query.ToLower())).Select(x=>x.LocationId).ToList();
        if (findLocation.Any())
        {

            var checkLocations = _dbContext.ApplicationUsers.Where(c => ids.Contains(c.Id) && findLocation.Contains((int)c.LocationId)).Select(c => c.Id).ToList();

            if (checkLocations != null)
                locationUsers.AddRange(checkLocations);
        }

        List<string> interestsUsers = new List<string>();
        var category = _dbContext.Categories.Where(c => c.Name.ToLower().Contains(query.ToLower())).Select(c=>c.Id).ToList();
        if (category.Any())
        {

            var checkInterests = _dbContext.UserInterests.Where(c => category.Contains(c.CategoryId)).Select(c => c.ApplicationUserId).ToList();

            if (checkInterests != null)
                interestsUsers.AddRange(checkInterests);
        }

        var result = (from t1 in _dbContext.ApplicationUsers
                      from t2 in _dbContext.ConnectorLocations
                      where t2.SiteId == siteId && t1.Id.Contains(t2.ApplicationUserId) &&( t1.Gender == query || t1.Email == query|| t1.PhoneNumber==query||religionUsers.Contains(t2.ApplicationUserId) || interestsUsers.Contains(t2.ApplicationUserId) || locationUsers.Contains(t2.ApplicationUserId) || ageUsers.Contains(t2.ApplicationUserId) ||t1.Name == query|| t1.UserName==query)
                      select new{userName = t1.UserName,profilePicture = t1.ProfilePicture }).Skip(skip).Take(10).Distinct().ToList();

        var json = JsonSerializer.Serialize(result);
        return json;

    }
...