示例#1
0
        public IActionResult SearchAds([FromBody] AdSearchDto options)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState.Errors()));
            }

            KeyValuePair <bool, string> kvp = options.IsValidSearchInputs(_configuration, _jsonDataService);

            if (kvp.Key)
            {
                return(BadRequest("In valid inputs: " + kvp.Value));
            }

            var anonymous = _adSearchService.SearchAds(options);

            return(Ok(anonymous));
        }
示例#2
0
        public static KeyValuePair <bool, string> IsValidSearchInputs(this AdSearchDto options, IJsonDataService _jsonDataService)
        {
            List <string> errors = new List <string>();

            if (!string.IsNullOrEmpty(options.SearchText))
            {
                options.IsValidSearchText = true;
                options.SearchText        = options.SearchText.Trim().ToLower();
            }

            options.IsValidCategory = true;
            options.ConditionId     = _jsonDataService.GetCategoryOrDefault(options.CategoryId).Key;

            options.IsValidCondition = true;
            options.ConditionId      = _jsonDataService.GetConditionOrDefault(options.ConditionId).Key;

            if (_jsonDataService.IsValidCountryCode(options.CountryCode))
            {
                options.IsValidCountryCode = true;
                options.CountryCode        = options.CountryCode.Trim().ToUpper();
            }

            if (_jsonDataService.IsValidCurrencyCode(options.CurrencyCode))
            {
                options.IsValidCurrencyCode = true;
                options.CurrencyCode        = options.CurrencyCode.Trim().ToUpper();
            }

            if (!string.IsNullOrEmpty(options.CityName))
            {
                options.IsValidCityName = true;
                options.CityName        = options.CityName.Trim().ToLower();
            }

            if (!string.IsNullOrEmpty(options.ZipCode))
            {
                options.IsValidZipCode = true;
                options.ZipCode        = options.ZipCode.Trim().ToLower();
            }

            if (!string.IsNullOrWhiteSpace(options.MinPrice) && !string.IsNullOrWhiteSpace(options.MaxPrice))
            {
                options.ItemCostMin = Utility.ConvertToDoubleFromString(options.MinPrice);
                options.ItemCostMax = Utility.ConvertToDoubleFromString(options.MaxPrice);
                if (options.ItemCostMin >= 0 && options.ItemCostMax >= 0 && options.ItemCostMin <= options.ItemCostMax)
                {
                    options.IsValidPrice = true;
                }
            }
            else if (!string.IsNullOrWhiteSpace(options.MinPrice) && string.IsNullOrWhiteSpace(options.MaxPrice))
            {
                options.ItemCostMin = Utility.ConvertToDoubleFromString(options.MinPrice);
                if (options.ItemCostMin > 0)
                {
                    options.IsValidMinPrice = true;
                }
            }
            else if (string.IsNullOrWhiteSpace(options.MinPrice) && !string.IsNullOrWhiteSpace(options.MaxPrice))
            {
                options.ItemCostMax = Utility.ConvertToDoubleFromString(options.MaxPrice);
                if (options.ItemCostMax > 0)
                {
                    options.IsValidMaxPrice = true;
                }
            }

            KeyValueDescription mileOption = _jsonDataService.GetMileOptionById(options.MileOptionsId);

            if (mileOption != null)
            {
                options.IsValidMileOption = true;
                if (options.MileOptionsId == byte.MaxValue)
                {
                    options.Miles = double.MaxValue;
                }
                else
                {
                    options.Miles = options.MileOptionsId;
                }
            }

            options.IsValidSortOption = true;
            options.SortOptionsId     = _jsonDataService.GetSortOptionByIdOrDefault(options.SortOptionsId).Key;

            if (!string.IsNullOrWhiteSpace(options.MapLattitude) &&
                !string.IsNullOrWhiteSpace(options.MapLongitude) &&
                Utility.IsValidLatitude(options.MapLattitude) &&
                Utility.IsValidLongitude(options.MapLongitude))
            {
                IPoint point = Utility.CreatePoint(longitude: options.MapLongitude, latitude: options.MapLattitude);
                if (point != null)
                {
                    options.IsValidLocation = true;
                    options.MapLocation     = point;
                }
            }

            return(new KeyValuePair <bool, string>(errors.Count > 0, string.Join(Path.PathSeparator, errors)));
        }
示例#3
0
        //https://gunnarpeipman.com/net/ef-core-paging/
        //https://dzone.com/articles/using-the-angular-material-paginator-with-aspnet-c
        //https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-2.1
        //https://docs.microsoft.com/en-us/sql/relational-databases/search/query-with-full-text-search?view=sql-server-2017
        //https://github.com/uber-asido/backend/blob/e32bf1ddabe500002d835228993707503449e06c/src/Uber.Module.Search.EFCore/Store/SearchItemStore.cs
        //https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/blob/42c335ceac6d93d1c0487ef45fc992810c07fd9d/upstream/EFCore.Upstream.FunctionalTests/Query/DbFunctionsMySqlTest.cs
        public dynamic SearchAds1(AdSearchDto options)
        {
            IQueryable <Share.Models.Ad.Entities.Ad> query = _adRepository.Entities.AsNoTracking().TagWith(nameof(SearchAds)).Where(w => w.IsPublished && w.IsActivated && !w.IsDeleted);

            #region FreeText
            //int language = _configuration["SqlServerFullTextIndexLanguage"].ConvertToInt();
            //int lcid = CultureInfo.CurrentCulture.LCID; // 1033 is coming
            // implemented and chosen FreeText from 4 options: 1.FreeText 2.Contains 3.ContainsTable 4.FreeTextTable
            // figure out later: SqlServerDbFunctionsExtensions
            if (options.IsValidSearchText)
            {
                query = query.Where(ft => EF.Functions.FreeText(ft.AdContent, options.SearchText) || EF.Functions.FreeText(ft.AdTitle, options.SearchText));
                //query = query.Where(ft => EF.Functions.FreeText(ft.AdTitle, options.SearchText));
            }
            #endregion

            #region General
            if (options.IsValidCategory)
            {
                query = query.Where(q => q.AdCategoryId == options.CategoryId);
            }
            if (options.IsValidCondition)
            {
                query = query.Where(q => q.ItemConditionId == options.ConditionId);
            }
            if (options.IsValidCountryCode)
            {
                query = query.Where(q => q.AddressCountryCode.Trim().ToUpper() == options.CountryCode);
            }
            if (options.IsValidCurrencyCode)
            {
                query = query.Where(q => q.ItemCurrencyCode.Trim().ToUpper() == options.CurrencyCode);
            }
            if (options.IsValidCityName)
            {
                query = query.Where(q => q.AddressCity.Trim().ToLower() == options.CityName);
            }
            if (options.IsValidZipCode)
            {
                query = query.Where(q => q.AddressZipCode.Trim().ToLower() == options.ZipCode);
            }
            #endregion

            #region Cost or Price
            if (options.IsValidPrice)
            {
                query = query.Where(q => q.ItemCost >= options.ItemCostMin && q.ItemCost <= options.ItemCostMax);
            }
            else if (options.IsValidMinPrice)
            {
                query = query.Where(q => q.ItemCost >= options.ItemCostMin);
            }
            else if (options.IsValidMinPrice)
            {
                query = query.Where(q => q.ItemCost <= options.ItemCostMax);
            }
            #endregion

            #region Sorting
            if (options.IsValidSortOption)
            {
                switch ((SortOptionsBy)options.SortOptionsId)
                {
                case SortOptionsBy.ClosestFirst:
                    // handled below in same function , ref : line #73
                    break;

                case SortOptionsBy.NewestFirst:
                    query = query.OrderByDescending(o => o.UpdatedDateTime);
                    break;

                case SortOptionsBy.PriceHighToLow:
                    query = query.OrderByDescending(o => o.ItemCost);
                    break;

                case SortOptionsBy.PriceLowToHigh:
                    query = query.OrderBy(o => o.ItemCost);
                    break;

                default:
                    break;
                }
            }
            #endregion

            #region Location
            if (options.IsValidLocation && (SortOptionsBy)options.SortOptionsId == SortOptionsBy.ClosestFirst)
            {
                if (options.IsValidMileOption)
                {
                    if ((MileOptionsBy)options.SortOptionsId == MileOptionsBy.Maximum)
                    {
                        query = query.OrderBy(o => o.AddressLocation.Distance(options.MapLocation));
                    }
                    else
                    {
                        query = query.OrderBy(o => o.AddressLocation.Distance(options.MapLocation) < options.Miles);
                    }
                }
                else
                {
                    query = query.OrderBy(o => o.AddressLocation.Distance(options.MapLocation));
                }
            }
            else if (options.IsValidLocation && options.IsValidMileOption)
            {
                if ((MileOptionsBy)options.SortOptionsId == MileOptionsBy.Maximum)
                {
                    query = query.OrderBy(o => o.AddressLocation.Distance(options.MapLocation));
                }
                else
                {
                    query = query.OrderBy(o => o.AddressLocation.Distance(options.MapLocation) < options.Miles);
                }
            }
            #endregion

            #region Pagination
            PagedResult <AdDto> pagedResult = query.GetPaged <Share.Models.Ad.Entities.Ad, AdDto>(options.Page, options.PageSize, options.IsValidPageCount, options.PageCount);
            _adRepository.Context.Dispose();
            #endregion

            return(new { PagedResult = pagedResult, options = options });
        }
示例#4
0
        //https://dzone.com/articles/using-the-angular-material-paginator-with-aspnet-c
        // https://github.com/dncuug/X.PagedList
        //https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-2.1
        //https://docs.microsoft.com/en-us/sql/relational-databases/search/query-with-full-text-search?view=sql-server-2017
        //https://github.com/uber-asido/backend/blob/e32bf1ddabe500002d835228993707503449e06c/src/Uber.Module.Search.EFCore/Store/SearchItemStore.cs
        //https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/blob/42c335ceac6d93d1c0487ef45fc992810c07fd9d/upstream/EFCore.Upstream.FunctionalTests/Query/DbFunctionsMySqlTest.cs
        public dynamic SearchAds(AdSearchDto options)
        {
            IQueryable <Share.Models.Ad.Entities.Ad> query = _adRepository.Entities.AsNoTracking().Where(w => w.IsPublished && w.IsActivated && !w.IsDeleted);

            // implemented and chosen FreeText from 4 options: 1.FreeText 2.Contains 3.ContainsTable 4.FreeTextTable
            // figure out later: SqlServerDbFunctionsExtensions
            if (options.IsValidSearchText)
            {
                //query = query.Where(ft => EF.Functions.FreeText(ft.AdContent, options.SearchText));
                query = query.Where(ft => EF.Functions.FreeText(ft.AdTitle, options.SearchText));
            }

            string      connection    = "Server=localhost;Database=Ad;Trusted_Connection=True;";
            var         optionBuilder = new DbContextOptionsBuilder <AdDbContext>().UseSqlServer(connection, ya => ya.UseNetTopologySuite());
            AdDbContext context       = new AdDbContext(optionBuilder.Options);

            IQueryable <Share.Models.Ad.Entities.Ad> query12 = context.Ads.Where(w => w.IsPublished && w.IsActivated && !w.IsDeleted);
            var sfsfs = query12.ToList();

            IQueryable <Share.Models.Ad.Entities.Ad> query1 = context.Ads.Where(ft => EF.Functions.Contains(ft.AdTitle, "title", 1033));
            var aaa = query1.ToList();
            //query1 = query1.Where(ft => EF.Functions.FreeText(ft.AdTitle, "title", 1033));  // 0: newtral, 1033: english

            string sql = query1.ToSql <Share.Models.Ad.Entities.Ad>();


            if (options.IsValidCategory)
            {
                query = query.Where(q => q.AdCategoryId == options.CategoryId);
            }
            if (options.IsValidCondition)
            {
                query = query.Where(q => q.ItemConditionId == options.ConditionId);
            }
            if (options.IsValidCountryCode)
            {
                query = query.Where(q => q.AddressCountryCode.Trim().ToUpper() == options.CountryCode);
            }
            if (options.IsValidCurrencyCode)
            {
                query = query.Where(q => q.ItemCurrencyCode.Trim().ToUpper() == options.CurrencyCode);
            }
            if (options.IsValidCityName)
            {
                query = query.Where(q => q.AddressCity.Trim().ToLower() == options.CityName);
            }
            if (options.IsValidZipCode)
            {
                query = query.Where(q => q.AddressZipCode.Trim().ToLower() == options.ZipCode);
            }

            if (options.IsValidPrice)
            {
                query = query.Where(q => q.ItemCost >= options.ItemCostMin && q.ItemCost <= options.ItemCostMax);
            }
            else if (options.IsValidMinPrice)
            {
                query = query.Where(q => q.ItemCost >= options.ItemCostMin);
            }
            else if (options.IsValidMinPrice)
            {
                query = query.Where(q => q.ItemCost <= options.ItemCostMax);
            }


            if (options.IsValidSortOption)
            {
                switch ((SortOptionsBy)options.SortOptionsId)
                {
                case SortOptionsBy.ClosestFirst:
                    // handled below in same function , ref : line #73
                    break;

                case SortOptionsBy.NewestFirst:
                    query = query.OrderByDescending(o => o.UpdatedDateTime);
                    break;

                case SortOptionsBy.PriceHighToLow:
                    query = query.OrderByDescending(o => o.ItemCost);
                    break;

                case SortOptionsBy.PriceLowToHigh:
                    query = query.OrderBy(o => o.ItemCost);
                    break;

                default:
                    break;
                }
            }

            if ((SortOptionsBy)options.SortOptionsId == SortOptionsBy.ClosestFirst && options.IsValidLocation)
            {
                if (options.IsValidMileOption)
                {
                    if ((MileOptionsBy)options.SortOptionsId == MileOptionsBy.Maximum)
                    {
                        query = query.OrderBy(o => o.AddressLocation.Distance(options.MapLocation));
                    }
                    else
                    {
                        query = query.OrderBy(o => o.AddressLocation.Distance(options.MapLocation) < options.Miles);
                    }
                }
                else
                {
                    query = query.OrderBy(o => o.AddressLocation.Distance(options.MapLocation));
                }
            }
            else if (options.IsValidMileOption && options.IsValidLocation)
            {
                if ((MileOptionsBy)options.SortOptionsId == MileOptionsBy.Maximum)
                {
                    query = query.OrderBy(o => o.AddressLocation.Distance(options.MapLocation));
                }
                else
                {
                    query = query.OrderBy(o => o.AddressLocation.Distance(options.MapLocation) < options.Miles);
                }
            }

            List <Share.Models.Ad.Entities.Ad> a = query.ToList();

            //paging
            query = query.Take(options.DefaultPageSize);

            // select columns:
            List <AdDto> adDtos = query.Select(s => new AdDto()
            {
                AdId    = s.AdId.ToString(),
                AdTitle = s.AdTitle,
                UpdatedDateTimeString = s.UpdatedDateTime.TimeAgo(),
                UserIdOrEmail         = s.UserIdOrEmail,
            }).ToList <AdDto>();



            return(new { records = adDtos, options = options });
        }
示例#5
0
        public static KeyValuePair <bool, string> IsValidSearchInputs(this AdSearchDto options, IConfiguration _configuration, IJsonDataService _jsonDataService)
        {
            List <string> errors = new List <string>();

            #region All General
            if (string.IsNullOrWhiteSpace(_configuration["SqlServerFullTextIndexLanguage"]))
            {
                errors.Add("SqlServerFullTextIndexLanguage");
            }

            if (!string.IsNullOrEmpty(options.SearchText))
            {
                options.IsValidSearchText = true;
                options.SearchText        = options.SearchText.Trim().ToLower();
            }

            options.IsValidCategory = true;
            options.ConditionId     = _jsonDataService.GetCategoryOrDefault(options.CategoryId).Key;

            options.IsValidCondition = true;
            options.ConditionId      = _jsonDataService.GetConditionOrDefault(options.ConditionId).Key;

            if (_jsonDataService.IsValidCountryCode(options.CountryCode))
            {
                options.IsValidCountryCode = true;
                options.CountryCode        = options.CountryCode.Trim().ToUpper();
            }

            if (_jsonDataService.IsValidCurrencyCode(options.CurrencyCode))
            {
                options.IsValidCurrencyCode = true;
                options.CurrencyCode        = options.CurrencyCode.Trim().ToUpper();
            }

            if (!string.IsNullOrEmpty(options.CityName))
            {
                options.IsValidCityName = true;
                options.CityName        = options.CityName.Trim().ToLower();
            }

            if (!string.IsNullOrEmpty(options.ZipCode))
            {
                options.IsValidZipCode = true;
                options.ZipCode        = options.ZipCode.Trim().ToLower();
            }
            #endregion

            #region Price
            if (!string.IsNullOrWhiteSpace(options.MinPrice) && !string.IsNullOrWhiteSpace(options.MaxPrice))
            {
                options.ItemCostMin = options.MinPrice.ConvertToDoubleOrZero();
                options.ItemCostMax = options.MaxPrice.ConvertToDoubleOrZero();
                if (options.ItemCostMin >= 0 && options.ItemCostMax >= 0 && options.ItemCostMin <= options.ItemCostMax)
                {
                    options.IsValidPrice = true;
                }
            }
            else if (!string.IsNullOrWhiteSpace(options.MinPrice) && string.IsNullOrWhiteSpace(options.MaxPrice))
            {
                options.ItemCostMin = options.MinPrice.ConvertToDoubleOrZero();
                if (options.ItemCostMin > 0)
                {
                    options.IsValidMinPrice = true;
                }
            }
            else if (string.IsNullOrWhiteSpace(options.MinPrice) && !string.IsNullOrWhiteSpace(options.MaxPrice))
            {
                options.ItemCostMax = options.MaxPrice.ConvertToDoubleOrZero();
                if (options.ItemCostMax > 0)
                {
                    options.IsValidMaxPrice = true;
                }
            }
            #endregion

            #region Mile Option
            KeyValueDescription mileOption = _jsonDataService.GetMileOptionById(options.MileOptionsId);
            if (mileOption != null)
            {
                options.IsValidMileOption = true;
                if (options.MileOptionsId == byte.MaxValue)
                {
                    options.Miles = double.MaxValue;
                }
                else
                {
                    options.Miles = options.MileOptionsId;
                }
            }
            #endregion

            #region Location
            if (options.MapLongitude.IsValidLocation(options.MapLatitude))
            {
                options.IsValidLocation = true;
            }

            if (options.IsValidLocation)
            {
                options.Longitude   = options.MapLongitude.ConvertToDouble();
                options.Latitude    = options.MapLatitude.ConvertToDouble();
                options.MapLocation = new Point(options.Longitude, options.Latitude)
                {
                    SRID = 4326
                };
            }
            #endregion

            #region Pagination
            if (options.PageSize <= 0)
            {
                options.PageSize = _configuration["DefaultItemsCount"].ConvertToInt();
            }
            if (options.PageCount.HasValue && options.PageCount.Value > 0)
            {
                options.IsValidPageCount = true;
            }
            else
            {
                options.IsValidPageCount = false;
                options.PageCount        = default(int?);
            }
            if (options.Page < 1)
            {
                options.Page = 1;
            }
            else if (options.IsValidPageCount && options.PageCount.Value < options.Page)
            {
                options.Page = options.PageCount.Value;
            }
            #endregion

            #region Sorting
            options.IsValidSortOption = true;
            options.SortOptionsId     = _jsonDataService.GetSortOptionByIdOrDefault(options.SortOptionsId).Key;
            #endregion

            return(new KeyValuePair <bool, string>(errors.Count > 0, string.Join(Path.PathSeparator, errors)));
        }