protected void ProcessSpecification(ICriteria queryCriteria, TEntity specification) { if (specification != null) { var propertyValuePairs = specification.ToDictionary( (descriptor, o) => ShouldIncludeInQueryCriteria(descriptor, o, specification)); foreach (var key in propertyValuePairs.Keys) { IHasLookupColumnPropertyMap map = specification as IHasLookupColumnPropertyMap; if (map.IdPropertyByLookupProperty.TryGetValue(key, out LookupColumnDetails columnDetails)) { // Look up the corresponding lookup id value from the cache var lookupId = _descriptorsCache.GetId( columnDetails.LookupTypeName, Convert.ToString(propertyValuePairs[key])); // Add criteria for the lookup Id value, to avoid need to incorporate an INNER JOIN into the query queryCriteria.Add( propertyValuePairs[key] != null ? Restrictions.Eq(columnDetails.PropertyName, lookupId) : Restrictions.IsNull(key)); } else { // Add the property equality condition to the query criteria queryCriteria.Add( propertyValuePairs[key] != null ? Restrictions.Eq(key, propertyValuePairs[key]) : Restrictions.IsNull(key)); } } } }
public void ApplyChildResource( HqlBuilderContext builderContext, CompositeDefinitionProcessorContext processorContext) { builderContext.CurrentAlias = builderContext.AliasGenerator.GetNextAlias(); builderContext.From.AppendFormat( "{0}\tjoin {1}.{2} {3}", Environment.NewLine, builderContext.ParentAlias, processorContext.EntityMemberName, builderContext.CurrentAlias); var collection = processorContext.CurrentResourceMember as Collection; if (collection != null && collection.ValueFilters.Length > 0) { StringBuilder filterWhere = new StringBuilder(); foreach (var valueFilter in collection.ValueFilters) { // Get the actual filter to which the property applies var filterProperty = collection.ItemType.AllPropertyByName[valueFilter.PropertyName]; string parameterName = builderContext.CurrentAlias + "_" + valueFilter.PropertyName + "_" + (valueFilter.FilterMode == ItemFilterMode.ExcludeOnly ? "0" : "1"); // Set the filter values object parametersAsObject; // Is this a first time parameter value assignment? if (!builderContext.CurrentQueryFilterParameterValueByName.TryGetValue(parameterName, out parametersAsObject)) { // Process filters into the query filterWhere.AppendFormat( "{0}{1}.{2}Id {3} (:{4})", OrIfNeeded(filterWhere), builderContext.CurrentAlias, valueFilter.PropertyName, valueFilter.FilterMode == ItemFilterMode.ExcludeOnly ? "NOT IN" : "IN", parameterName); // Set the parameter values builderContext.CurrentQueryFilterParameterValueByName[parameterName] = valueFilter.Values .Select(x => _descriptorsCache.GetId(filterProperty.LookupTypeName, x)) .ToArray(); } else { // Concatenate the current filter's values to the existing parameter list builderContext.CurrentQueryFilterParameterValueByName[parameterName] = (parametersAsObject as int[]) .Concat( valueFilter.Values .Select(x => _descriptorsCache.GetId(filterProperty.LookupTypeName, x)) ) .ToArray(); } } // Apply all the filters using an AND clause builderContext.Where.AppendFormat( "{0}({1})", AndIfNeeded(builderContext.Where), filterWhere); } }