snippetcsharpMinor
Filter mapping system
Viewed 0 times
mappingsystemfilter
Problem
This system allows the user to define property mappings between two objects and a filter. Then the user may call
Example Setup
Example Usage
Code
```
///
/// Defines an interface for producing a filter expression (predicate) for a type given a property selector on that type and a criteria/search value.
///
public interface IFilter
{
Expression> GetFilterExpression(object searchValue, Expression> filterPropertySelector);
}
///
/// Allows the configuration and application of filters from one object type's property to another object type's property.
/// Recommended placing configuration in a App_Start and then calling it in the Application_Start() in Global.asax.
///
public class Filters
{
///
/// All mappings currently configured for the application.
/// The key being the model type and the value being a collection of mappings from one property to another.
///
protected static IDictionary> Mappings = new Dictionary>();
///
/// Allows the configuration of mappings from a search model's property val
Filters.Apply() to get an IQueryable.Example Setup
// Called from some program entry point.
Filters.Configure()
.Map(x => x.SearchName, x => x.Name)
.Map(x => x.SearchType, x => x.Type)
.Map(x => x.SearchX, x => x.X)
.Map(x => x.SearchY, x => x.Y)
.Map(x => x.SearchNotBroken, x => x.IsBroken);
public class TileVM
{
public string SearchName { get; set; }
public string SearchType { get; set; }
public int? SearchX { get; set; }
public int? SearchY { get; set; }
public bool? SearchNotBroken { get; set; }
}
public class Tile
{
public string Name { get; set; }
public string Type { get; set; }
public int X { get; set; }
public int Y { get; set; }
public bool IsBroken { get; set; }
}Example Usage
var vm = TileVM() { ... };
var Db = new DbContext();
var query = Filters.Apply(vm, Db.Tiles.ReadAll());Code
```
///
/// Defines an interface for producing a filter expression (predicate) for a type given a property selector on that type and a criteria/search value.
///
public interface IFilter
{
Expression> GetFilterExpression(object searchValue, Expression> filterPropertySelector);
}
///
/// Allows the configuration and application of filters from one object type's property to another object type's property.
/// Recommended placing configuration in a App_Start and then calling it in the Application_Start() in Global.asax.
///
public class Filters
{
///
/// All mappings currently configured for the application.
/// The key being the model type and the value being a collection of mappings from one property to another.
///
protected static IDictionary> Mappings = new Dictionary>();
///
/// Allows the configuration of mappings from a search model's property val
Solution
-
You shouldn't have to compile this on every search:
Instead you should be able to store the compiled delegate when setting up the mapping.
-
Similarly it might be an option to pre-create the
-
In
-
Since in
You shouldn't have to compile this on every search:
(mapping.SearchPropertySelector as Expression>).Compile()Instead you should be able to store the compiled delegate when setting up the mapping.
-
Similarly it might be an option to pre-create the
IFilter instance - either per FilterType (becomes a singleton) or per mapping. Given that these filter instances seem like they should be stateless anyway having them as per-type singleton might be a viable approach.-
In
Map TF should be restricted with where TF: IFilter or else your Apply may throw a NullReferenceException-
Since in
Apply you currently can't deal with filterProvider being null you should not use as but a direct cast instead.Code Snippets
(mapping.SearchPropertySelector as Expression<Func<TVM, object>>).Compile()Context
StackExchange Code Review Q#109306, answer score: 4
Revisions (0)
No revisions yet.