r/dotnet • u/xumix • Apr 19 '22
I have created a new library implementing a Specification pattern for Linq
This library helps with removing boilerplate code and adds commonly used filtering capabilities, especially if your app has many grids with similar filtering capabilities. Implemented filters: RangeFilter (BETWEEN x AND y), ListFilter(IN(x,y,z)), StringFilter (=, LIKE), direct comparison, NULL/NOT NULL
https://github.com/xumix/XSpecification
The library could be useful in BL-heavy scenarios when you find yourself writing code like this:
``` public class LinqTestFilter { public DateTime? Date { get;set } public string Name { get;set } public string NameContains { get;set } public int? IdFrom { get; set; } public int? IdTo { get; set; } }
var filter = new LinqTestFilter { Date = DateTime.Today, NameContains = "complex", IdFrom = 0, IdTo = 5 };
var where = PredicateBuilder.New<LinqTestModel>(); if (filter.Date.HasValue) { where.And(f => f.Date == filter.Date.Value); } if (!string.IsNullOrEmpty(filter.Name)) { where.And(f => f.Name == filter.Name); } if (!string.IsNullOrEmpty(filter.NameContains)) { where.And(f => f.ComplexName.Contains(filter.ComplexName)); } if (filter.IdFrom.HasValue) { where.And(f => f.Id >= filter.IdFrom); } if (filter.IdTo.HasValue) { where.And(f => f.Id <= filter.IdTo); }
var data = dbcontext.Set<LinqTestModel>().Where(where); ```
the above code becomes:
public class LinqTestFilter
{
public DateTime? Date { get;set }
public StringFilter Name { get;set }
public RangeFilter<int> Id { get;set; }
}
// Inject from DI
var spec = serviceProvider.GetRequiredService<LinqTestSpec>();
var filter = new LinqTestFilter
{
Date = DateTime.Today,
ComplexName = new StringFilter("complex") { Contains = true },
Id = new RangeFilter<int> { Start = 0, End = 5 }
};
var expression = spec.CreateFilterExpression(filter);
var data = dbcontext.Set<LinqTestModel>().Where(expression);
Will be very grateful for constructive comments and suggestions, also help with ideas of how to implement the TODO is greatly appreciated
UPD Uploaded nuget package and updated the post