Skip to content

Instantly share code, notes, and snippets.

@jcteague
Created June 4, 2011 05:19
Show Gist options
  • Save jcteague/1007612 to your computer and use it in GitHub Desktop.
Save jcteague/1007612 to your computer and use it in GitHub Desktop.
Convention Approach to Creating Filters with Nhibernate
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; }
}
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;
}
}
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