private Expression <Func <T, bool> > BuildGlobalQueryCondition <T>(BuildQueryContainer <T> queryContainer) where T : class { var where = new List <Expression <Func <T, bool> > >(); var property = new WhereQueryProperty { Operator = CompareOperator.Contains, SearchTerm = queryContainer.QueryParameters.SearchTerm }; foreach (var propertyInfo in queryContainer.PropertyInfos) { property.PropertyName = propertyInfo.Name; if (queryContainer.Mappings.ContainsKey(propertyInfo.Name)) { where.AddRange(queryContainer.Mappings[propertyInfo.Name].Select(m => GetMappingCondition(property, m, _typeString)).Where(e => e != null).ToList()); } else if (propertyInfo.PropertyType == _typeString) { var condition = GetPropertyCondition <T>(property, queryContainer.PropertyInfos, queryContainer.Parameter); if (condition != null) { where.Add(condition); } } } return(where.Any() ? JoinOrExpressions(where) : null); }
private Expression <Func <T, bool> > BuildGlobalQueryCondition <T>(BuildQueryContainer <T> queryContainer) where T : class { var where = new List <Expression <Func <T, bool> > >(); var searchTermParts = new[] { queryContainer.QueryParameters.SearchTerm }; if (_options.ContainsSearchSplitBySpace) { searchTermParts = queryContainer.QueryParameters.SearchTerm.Split(' ').Where(t => !t.IsNullOrEmpty()).ToArray(); } var andExpressions = new List <Expression <Func <T, bool> > >(); foreach (var searchTermPart in searchTermParts) { var property = new WhereQueryProperty { Operator = CompareOperator.Contains, SearchTerm = searchTermPart }; var orExpressions = new List <Expression <Func <T, bool> > >(); foreach (var propertyInfo in queryContainer.PropertyInfos) { property.PropertyName = propertyInfo.Name; if (queryContainer.Mappings.ContainsKey(propertyInfo.Name)) { orExpressions.AddRange(queryContainer.Mappings[propertyInfo.Name].SelectMany(m => GetMappingCondition(property, m, _typeString)).Where(e => e != null).ToList()); } else if (propertyInfo.PropertyType == _typeString && propertyInfo.GetCustomAttribute <QueryIgnoreAttribute>() == null) { var conditions = GetPropertyCondition <T>(property, queryContainer.PropertyInfos, queryContainer.Parameter); if (conditions.Any()) { orExpressions.AddRange(conditions); } } } foreach (var mapping in queryContainer.Mappings) { if (queryContainer.PropertyInfos.Any(propertyInfo => propertyInfo.Name == mapping.Key)) { continue; } orExpressions.AddRange(mapping.Value.SelectMany(m => GetMappingCondition(property, m, _typeString)).Where(e => e != null).ToList()); } if (orExpressions.Count > 0) { andExpressions.Add(JoinOrExpressions(orExpressions)); } } return(JoinAndExpressions(andExpressions)); }
/// <summary> /// Creates a list of where expression based on passed query parameters /// </summary> /// <remarks> /// Global search term is only supported for string properties in the data type class <see cref="T">T</see>. /// String properties in sub classes or enumerable string properties are not supported. /// </remarks> /// <typeparam name="T">Class data type</typeparam> /// <param name="queryParameters">queryParameters</param> /// <param name="mappings">Mappings for foreign key properties</param> /// <exception cref="ArgumentNullException">Thrown if <see cref="QueryParameters">queryParameters</see> is null.</exception> /// <returns> where expressions</returns> public IEnumerable <Expression <Func <T, bool> > > BuildQueryExpressions <T>(QueryParameters queryParameters, Dictionary <string, List <Expression <Func <T, object> > > > mappings = null) where T : class { if (queryParameters == null) { throw new ArgumentNullException(nameof(queryParameters)); } var where = new List <Expression <Func <T, bool> > >(); var hasPropertyQueries = queryParameters.WhereQueryProperties?.Any() ?? false; var hasGlobalSearchTerm = !queryParameters.SearchTerm.IsNullOrEmpty(); if (!hasPropertyQueries && !hasGlobalSearchTerm) { return(where); } if (mappings == null) { mappings = new Dictionary <string, List <Expression <Func <T, object> > > >(); } var type = typeof(T); var queryContainer = new BuildQueryContainer <T> { Mappings = mappings, Parameter = Expression.Parameter(type, "p"), PropertyInfos = type.GetProperties(), QueryParameters = queryParameters }; if (hasPropertyQueries) { where.AddRange(BuildPropertyQueryConditions(queryContainer)); } if (hasGlobalSearchTerm) { var condition = BuildGlobalQueryCondition(queryContainer); if (condition != null) { where.Add(condition); } } return(where); }
private IEnumerable <Expression <Func <T, bool> > > BuildPropertyQueryConditions <T>(BuildQueryContainer <T> queryContainer) where T : class { var where = new List <Expression <Func <T, bool> > >(); foreach (var property in queryContainer.QueryParameters.WhereQueryProperties) { var conditions = new List <Expression <Func <T, bool> > >(); if (queryContainer.Mappings.ContainsKey(property.PropertyName)) { var members = queryContainer.Mappings[property.PropertyName].Select(m => JoinAndExpressions(GetMappingCondition(property, m))).Where(e => e != null).ToList(); if (members.Count == 1) { conditions.Add(members.Single()); } else if (members.Count > 1) { conditions.Add(JoinOrExpressions(members)); } } else { conditions.AddRange(GetPropertyCondition <T>(property, queryContainer.PropertyInfos, queryContainer.Parameter)); } if (conditions.Any()) { where.AddRange(conditions); } } return(where); }