Last active
December 17, 2015 22:09
-
-
Save Dillie-O/5679454 to your computer and use it in GitHub Desktop.
Refactored BuildObjectQuery method
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static ObjectQuery<T> BuildObjectQuery<T> | |
(ObjectQuery<T> query, NameValueCollection parameters, | |
Dictionary<string, SearchParameter> searchCriteria) | |
{ | |
var results = query; | |
// If there are parameters in our collection, build a where clause | |
// using the search criteria dictionary. Otherwise the method ends | |
// and the query remains the same. | |
if (parameters.Count > 0) | |
{ | |
var whereClause = new StringBuilder(); | |
var isFirstParameter = true; | |
// Before processing parameters, check for from/to pairings for | |
// range queries. If a pairing exists, replace with the | |
// appropriate range key. | |
var keys = parameters.AllKeys.ToList(); | |
foreach (var key in keys) | |
{ | |
// Since parameters can be removed midloop, check for value | |
// before processing | |
if (!parameters.AllKeys.Contains(key)) continue; | |
// Test for from and to index values for simplified processing | |
var indexFrom = key.IndexOf("From", StringComparison.Ordinal); | |
var indexTo = key.IndexOf("To", StringComparison.Ordinal); | |
// Skip key if it is not a from/to parameter. | |
if (indexFrom <= 0 && indexTo <= 0) continue; | |
// Process parameter based on what name was found (from/to). | |
var keyPrefix = indexFrom > 0 ? key.Substring(0, indexFrom) : key.Substring(0, indexTo); | |
var fromKey = keyPrefix + "From"; | |
var toKey = keyPrefix + "To"; | |
// Make sure that there is a From and a To key to process. | |
if (!parameters.AllKeys.Contains(fromKey) || !parameters.AllKeys.Contains(toKey)) continue; | |
// Add range parameter, remove corresponding from/to | |
// parameters, and remove paired from/to key to prevent | |
// duplicate processing. | |
var rangeValue = parameters[fromKey] + "|" + parameters[toKey]; | |
parameters.Add(keyPrefix + "Range", rangeValue); | |
parameters.Remove(keyPrefix + "From"); | |
parameters.Remove(keyPrefix + "To"); | |
} | |
for (var i = 0; i < parameters.Count; i++) | |
{ | |
// Build Where clause | |
var itemKey = parameters.GetKey(i); | |
var itemValue = parameters.Get(i); | |
var itemClause = string.Empty; | |
SearchParameter criteria; | |
ObjectParameter queryParameter; | |
// Make sure search key exists | |
if (!searchCriteria.TryGetValue(itemKey, out criteria)) | |
{ | |
throw new Exception("Search Criteria Does Not Exist: " + itemKey); | |
} | |
if (!isFirstParameter) | |
{ | |
whereClause.Append(" AND "); | |
} | |
else | |
{ | |
isFirstParameter = false; | |
} | |
// Null item values avoid any kind of parameter processing and | |
// change the where clause slightly before appending to the query. | |
if (itemValue == "null") | |
{ | |
itemClause = criteria.WhereClause.Replace(" = {0}", " IS NULL"); | |
whereClause.Append(itemClause); | |
} | |
else | |
{ | |
// Most search criteria can simply be appended to the query. Some | |
// are multi-value selectors and need to be processed accordingly. | |
if (!criteria.AllowsMultipleValues) | |
{ | |
// Most parameters are single values, but if there is a range | |
// parameter we must split the values up. | |
if (!criteria.IsRangeSearch) | |
{ | |
itemClause = String.Format(criteria.WhereClause, "@" + criteria.VariableName); | |
whereClause.Append(itemClause); | |
// Add parameter to query | |
var valueText = itemValue; | |
if (criteria.IsWildcardSearch) | |
{ | |
valueText = "%" + valueText + "%"; | |
} | |
// Most of the time we use the value specified. However, null values | |
// require the DBNull value. | |
queryParameter = new ObjectParameter | |
(criteria.VariableName, criteria.ParameterType) | |
{ Value = valueText }; | |
query.Parameters.Add(queryParameter); | |
} | |
else | |
{ | |
// Use same variable name, simply append "From/To" to its name. | |
itemClause = String.Format(criteria.WhereClause, "@" + criteria.VariableName + "From", | |
"@" + criteria.VariableName + "To"); | |
whereClause.Append(itemClause); | |
// Add parameter to query | |
var splitValue = itemValue.Split('|'); | |
if (criteria.IsWildcardSearch) | |
{ | |
splitValue[0] = "%" + splitValue[0] + "%"; | |
splitValue[1] = "%" + splitValue[1] + "%"; | |
} | |
// Most of the time we use the value specified. However, null values | |
// require the DBNull value. | |
queryParameter = new ObjectParameter | |
(criteria.VariableName + "From", criteria.ParameterType) | |
{ Value = splitValue[0] }; | |
query.Parameters.Add(queryParameter); | |
// Most of the time we use the value specified. However, null values | |
// require the DBNull value. | |
queryParameter = new ObjectParameter | |
(criteria.VariableName + "To", criteria.ParameterType) | |
{ Value = splitValue[1] }; | |
query.Parameters.Add(queryParameter); | |
} | |
} | |
else | |
{ | |
// Parameter contains multiple values, which are split into a | |
// nested OR clause. | |
var values = itemValue.Split(',').Select(Convert.ToString).ToList(); | |
if (values.Count > 0) | |
{ | |
for (var j = 0; j <= values.Count - 1; j++) | |
{ | |
// Jump to next item in the loop if empty. | |
if (String.IsNullOrEmpty(values[j])) continue; | |
if (j != 0) | |
{ | |
whereClause.Append(" OR "); | |
} | |
else if (values.Count > 1) | |
{ | |
whereClause.Append(" ("); | |
} | |
itemClause = String.Format(criteria.WhereClause, "@" + criteria.VariableName + j); | |
whereClause.Append(itemClause); | |
// Add parameter to query | |
var valueText = values[j]; | |
if (criteria.IsWildcardSearch) | |
{ | |
valueText = "%" + valueText + "%"; | |
} | |
// Add parameter to query | |
queryParameter = new ObjectParameter | |
(criteria.VariableName + j, criteria.ParameterType) | |
{ Value = valueText }; | |
query.Parameters.Add(queryParameter); | |
} | |
if (values.Count > 1) | |
{ | |
whereClause.Append(") "); | |
} | |
} | |
} | |
} | |
} | |
// Append where clause to results. | |
results = query.Where(whereClause.ToString()); | |
} | |
return results; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment