Created
June 4, 2011 05:19
-
-
Save jcteague/1007612 to your computer and use it in GitHub Desktop.
Convention Approach to Creating Filters with Nhibernate
This file contains 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 class BasicFilter | |
{ | |
public Guid? ClientGroupId { get; set; } | |
[LikeQueryFilter(ComponentModel = typeof (Address))] | |
public string AddressCity { get; set; } | |
[QueryFilter(ComponentModel = typeof (Address))] | |
public string AddressState { get; set; } | |
[QueryFilter(ComponentModel = typeof (Address))] | |
public string AddressZip { get; set; } | |
[LikeQueryFilter(ComponentModel = typeof (Address))] | |
public string AddressLine1 { get; set; } | |
[LikeQueryFilter(ComponentModel = typeof (Address))] | |
public string AddressLine2 { get; set; } | |
public int? ClientId { get; set; } | |
public long? PropertyId { get; set; } | |
public Guid AssignedToUserId { get; set; } | |
} |
This file contains 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 class FilterQueryBuilder | |
{ | |
public IEnumerable<ICriterion> CreateFilter(object filter, Type objectToFilter) | |
{ | |
var criterion = new List<ICriterion>(); | |
var props = filter.GetType().GetProperties(); | |
foreach (var pi in props) | |
{ | |
var val = pi.GetValue(filter, null); | |
if (ShouldNotAddToFilter(pi, val)) continue; | |
var queryAttribute = (QueryFilterAttribute) pi.GetCustomAttributes(typeof (QueryFilterAttribute), true).FirstOrDefault(); | |
if (queryAttribute == null) | |
{ | |
criterion.Add(new SimpleExpression(pi.Name, val, "=")); | |
continue; | |
} | |
var name_to_return = GetNameFromAttribute(queryAttribute, pi, objectToFilter); | |
criterion.Add(queryAttribute.GetCriteria(name_to_return, val)); | |
} | |
return criterion; | |
} | |
static bool ShouldNotAddToFilter(PropertyInfo pi, object propertyValue) | |
{ | |
if (propertyValue == null) return true; | |
if(pi.GetCustomAttributes(false).Any(x=>x is NotAFilter)) return true; | |
return pi.PropertyType == typeof (Guid) && (Guid) propertyValue == Guid.Empty; | |
} | |
static string GetNameFromAttribute(QueryFilterAttribute queryAttribute, PropertyInfo filterProperty, Type objectToFilter) | |
{ | |
if (queryAttribute.ComponentModel == null) return filterProperty.Name; | |
var filter_property_name = filterProperty.Name; | |
var filtered_type_property_name = objectToFilter.GetProperties() | |
.Where(info => info.PropertyType == queryAttribute.ComponentModel && filter_property_name.StartsWith(info.Name)).First().Name; | |
var component_property_name = filterProperty.Name.Replace(filtered_type_property_name, ""); | |
return filtered_type_property_name + "." + component_property_name; | |
} | |
} |
This file contains 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 class NotAFilter: Attribute | |
{ | |
} | |
public class FilterGroup : Attribute | |
{ | |
public FilterGroup(string displayName) | |
{ | |
DisplayName = displayName; | |
} | |
public FilterGroup() | |
{ | |
} | |
public string DisplayName { get; set; } | |
} | |
public class QueryFilterAttribute : Attribute | |
{ | |
public virtual ICriterion GetCriteria(string propertyName, object val) | |
{ | |
return Restrictions.Eq(propertyName, val); | |
} | |
public Type ComponentModel { get; set; } | |
} | |
public class LikeQueryFilterAttribute : QueryFilterAttribute | |
{ | |
public override ICriterion GetCriteria(string propertyName, object val) | |
{ | |
return new LikeExpression(propertyName, val.ToString(), MatchMode.Anywhere); | |
} | |
} | |
public class DayPrecisionDateQueryFilterAttribute : QueryFilterAttribute | |
{ | |
public override ICriterion GetCriteria(string propertyName, object val) | |
{ | |
var value = (DateTimeOffset) val; | |
return new BetweenExpression(propertyName, value, value.AddDays(1).AddMilliseconds(-1)); | |
} | |
} | |
public class IgnoreFilterAttribute : QueryFilterAttribute | |
{ | |
public override ICriterion GetCriteria(string propertyName, object val) | |
{ | |
return new NotNullExpression(propertyName); | |
} | |
} | |
public class GreaterThanFilterAttribute : QueryFilterAttribute | |
{ | |
public override ICriterion GetCriteria(string propertyName, object val) | |
{ | |
return Restrictions.Gt(propertyName, val); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment