views:

44

answers:

0

I'm building a rather large filter based on an SearchObject that has 50+ fields that can be searched.

Rather than building my where clause for each one of these individually I thought I'd use some slight of hand and try building custom attribute suppling the necessary information and then using reflection to build out each of my predicate statements (Using LinqKit btw). Trouble is, that the code finds the appropriate values in the reflection code and successfully builds a predicate for the property, but the "where" doesn't seem to actually generate and my query always returns 0 records.

The attribute is simple:

[AttributeUsage(AttributeTargets.Property, AllowMultiple=true)]
public class FilterAttribute: Attribute
{
    public FilterType FilterType { get; set; } //enum{ Object, Database}
    public string FilterPath { get; set; }

    //var predicate = PredicateBuilder.False<Metadata>(); 
}

And this is my method that builds out the query:

public List<ETracker.Objects.Item> Search(Search SearchObject, int Page, int PageSize)
{
    var predicate = PredicateBuilder.False<ETracker.Objects.Item>();

    Type t = typeof(Search);
    IEnumerable<PropertyInfo> pi = t.GetProperties();
    string title = string.Empty;

    foreach (var property in pi)
    {
        if (Attribute.IsDefined(property, typeof(FilterAttribute)))
        {
            var attrs = property.GetCustomAttributes(typeof(FilterAttribute),true);
            var value = property.GetValue(SearchObject, null);
            if (property.Name == "Title")
                title = (string)value;
            predicate.Or(a => GetPropertyVal(a, ((FilterAttribute)attrs[0]).FilterPath) == value);
        }
    }

    var res = dataContext.GetAllItems().Take(1000)
                .Where(a => SearchObject.Subcategories.Select(b => b.ID).ToArray().Contains(a.SubCategory.ID))
                .Where(predicate);

    return res.ToList();
}

The SearchObject is quite simple:

public class Search
{
    public List<Item> Items { get; set; }

    [Filter(FilterType = FilterType.Object, FilterPath = "Title")]
    public string Title { get; set; }
    ...
}

Any suggestions will be greatly appreciated. I may well be going way the wrong direction and will take no offense if someone has a better alternative (or at least one that works)