Ejemplo n.º 1
0
        private static IEnumerable <T> _WeightedSearch <T>(IEnumerable <T> collection, string searchCriteria, string languageCode, bool removeItemsWithoutMatch = true)
        {
            #region Validations - validate parameter and collection items type

            if (collection == null)
            {
                throw new Exception("Passed value cannot be null.");
            }

            if (string.IsNullOrEmpty(searchCriteria))
            {
                return(collection);
            }

            if (!typeof(T).GetProperties().Any(x => x.CustomAttributes != null && x.CustomAttributes.Any(attribute => attribute.AttributeType == typeof(SearchWeight))))
            {
                throw new Exception("Collection type doesn't have any property designated for search.");
            }

            if (!typeof(T).GetProperties().Any(x => x.CustomAttributes != null && x.CustomAttributes.Any(attribute => attribute.AttributeType == typeof(WeightedSearchValue))))
            {
                throw new Exception("Collection type doesn't have a property designated for search result value.");
            }

            #endregion Validations - validate parameter and collection items type

            var propertiesForSearch = typeof(T).GetProperties().Where(x => x.CustomAttributes.Any(a => a.AttributeType == typeof(SearchWeight))).ToDictionary(x => x, x => ((SearchWeight)x.GetCustomAttributes(false).First(i => i is SearchWeight)).Weight);

            var propertyWithMatchingValue = typeof(T).GetProperties().First(x => x.CustomAttributes.Any(a => a.AttributeType == typeof(WeightedSearchValue)));

            var propertyWithNestedObject = typeof(T).GetProperties().FirstOrDefault(x => x.CustomAttributes.Any(a => a.AttributeType == typeof(SearchWeightNestedObject)));

            var searchTokens = searchCriteria.Trim().Contains(' ') ? searchCriteria.Trim().Split(' ') : new string[1] {
                searchCriteria.Trim()
            };

            var culture = Thread.CurrentThread.CurrentUICulture;

            if (!string.IsNullOrEmpty(languageCode))
            {
                culture = CultureInfo.GetCultures(CultureTypes.AllCultures).FirstOrDefault(x => x.Name.EndsWith("-" + languageCode.ToUpper()));
            }

            foreach (var item in collection)
            {
                var sum = _CalculateItemMatchingValue(item, propertiesForSearch, searchTokens, culture);

                // advanced - search through object tree
                if (propertyWithNestedObject != null && propertyWithNestedObject.GetValue(item) != null)
                {
                    var resultingObject = new MatchingValueObject();

                    _CalculateChildrenMatchingValue((IEnumerable <T>)propertyWithNestedObject.GetValue(item), searchTokens, propertiesForSearch, propertyWithNestedObject, resultingObject, culture);

                    sum += resultingObject.MatchingSum;
                }

                propertyWithMatchingValue.SetValue(item, sum);
            }

            if (removeItemsWithoutMatch)
            {
                var returnValue = collection.Where(x => (double)propertyWithMatchingValue.GetValue(x) > 0).OrderByDescending(x => (double)propertyWithMatchingValue.GetValue(x));

                return(returnValue);
            }
            else
            {
                return(collection);
            }
        }
Ejemplo n.º 2
0
        private static void _CalculateChildrenMatchingValue <T>(IEnumerable <T> childItems, string[] searchTokens, Dictionary <PropertyInfo, double> propertiesForSearch, PropertyInfo propertyWithNestedObject, MatchingValueObject resultObject, CultureInfo culture)
        {
            if (childItems != null && childItems.Any())
            {
                foreach (var item in childItems)
                {
                    resultObject.MatchingSum += _CalculateItemMatchingValue(item, propertiesForSearch, searchTokens, culture);

                    if (propertyWithNestedObject.GetValue(item) != null)
                    {
                        _CalculateChildrenMatchingValue((IEnumerable <T>)propertyWithNestedObject.GetValue(item), searchTokens, propertiesForSearch, propertyWithNestedObject, resultObject, culture);
                    }
                }
            }
        }