Using custom attributes to contain a target field/property for a search


Oct 22, 2014
Programming Experience
Big Picture
I maintain a large web application with the primary function of managing orders. It is an MVC over C# application using EF6 for data. There are LOTS of search screens. Right now every search is coded without any code re-use (before my time, I swear!).

What I'm Trying To Do
I'm building an inheritable search object so that, for any given search, I can build a derived class that lists the search fields and uses attributes to specify:

  • The display name of the field
  • The comparison type that will be done (= != > < <= >=)
  • The field of the target object to be searched
The base class then uses that information to put together a query.

My Struggle
The last attribute is the one that I'm having trouble with. How can I use an attribute to specify the target field of the object to be searched? My constraints:

- If at all possible I don't want to use a string here. I'd like to reference the field itself so that if we rename a field it doesn't break searches.
- The target field need to be able to target sub-objects as well. For example, the OrderNumber search field just needs to target Order.ID, but the Name search field needs to target Order.Customer.Name.
- The target cannot be the field of a specific instance of the object as this field is being used to generate a LINQ query.

Here's an example of a derived search class so you can see what it looks like. Thanks in advance for any guidance you can offer. Please note that the "LinkedField" attributes have been added to illustrate what I would LIKE to be there. It doesn't work, of course. :)

    //derived class that contains only the search fields
    public class OrderFilterSet: SearchTools.FilterSet 
        [LinkedField(/*??*/)] //should contain link to target field
        [Display(Name = "Order Number")]
        public string ID { get; set; }

        [Display(Name = "Current Status")]
        public string Status { get; set; }
        [Display(Name = "Set up on or before")]
        public DateTime CreatedDateEnd { get; set; }

        [Display(Name = "Set up on or after")]
        public DateTime CreatedDateStart { get; set; }

        [LinkedField(Order.Customer.Name] //note that target field is a sub-object
        [Display(Name = "Customer Name")]
        public string Name { get; set; }
Last edited:
Top Bottom