QueryableFilterSpecification 1.0.1
dotnet add package QueryableFilterSpecification --version 1.0.1
NuGet\Install-Package QueryableFilterSpecification -Version 1.0.1
<PackageReference Include="QueryableFilterSpecification" Version="1.0.1" />
<PackageVersion Include="QueryableFilterSpecification" Version="1.0.1" />
<PackageReference Include="QueryableFilterSpecification" />
paket add QueryableFilterSpecification --version 1.0.1
#r "nuget: QueryableFilterSpecification, 1.0.1"
#:package QueryableFilterSpecification@1.0.1
#addin nuget:?package=QueryableFilterSpecification&version=1.0.1
#tool nuget:?package=QueryableFilterSpecification&version=1.0.1
Give a Star! ⭐
If you like or are using this project please give it a star. Thanks!
Install
Current version of nuget package - https://www.nuget.org/packages/QueryableFilterSpecification/
The framework is provided as a set of NuGet packages.
To install the minimum requirements:
Install-Package QueryableFilterSpecification
Usage
This project is needed to facilitate the use of filters on large projects. For example, there is the following class
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
And for this class, we want to have a repository in which we want to filter this class for certain scenarios
public interface IPersonRepository
{
IEnumerable<Person> GetByName(string name);
IEnumerable<Person> GetByAge(int age);
IEnumerable<Person> GetByAgeAndName(int age, string name);
}
In this case, we see that this class is difficult to expand and the more properties the Person class has, the more filtering methods there will be. What solution do I propose? I propose to implement filters as a specification pattern, and connect and combine them as we need. Let's make the following filter specifications
public class PersonByNameFilterSpec : IQueryableFilterSpec<Person>
{
private readonly string _name;
public PersonByNameFilterSpec(string name)
{
_name = name;
}
public IQueryable<Person> ApplyFilter(IQueryable<Person> persons)
{
return persons.Where(ToExpression());
}
public Expression<Func<Person, bool>> ToExpression()
{
return p => p.Name.Contains(_name);
}
}
public class PersonByAgeFilterSpec : IQueryableFilterSpec<Person>
{
private readonly int _age;
public PersonByAgeFilterSpec(int age)
{
_age = age;
}
public IQueryable<Person> ApplyFilter(IQueryable<Person> persons)
{
return persons.Where(ToExpression());
}
public Expression<Func<Person, bool>> ToExpression()
{
return p => p.Age == _age;
}
}
Now we have specification filters. Let's change our IPersonRepository
public interface IPersonRepository
{
IEnumerable<Person> GetFilter(IQueryableFilterSpec<Person> filter);
}
public class PersonRepository : IPersonRepository
{
private readonly EFDbContext _context;
public PersonRepository(EFDbContext context)
{
_context = context;
}
public IEnumerable<Person> GetFilter(IQueryableFilterSpec<Person> filter)
{
return filter.ApplyFilter(_context.Persons);
}
}
Excellent! But how do we search by name and age?
//Search by name
var filterByName = new PersonByNameFilterSpec("Anton");
_personRepository.GetFilter(filterByName);
//Search by name or age
var filterByNameOrAge = new PersonByNameFilterSpec("Anton").Or(new PersonByAgeFilterSpec(20));
_personRepository.GetFilter(filterByNameOrAge);
//Search by name and age
var filterByNameAndAge = new PersonByNameFilterSpec("Anton").And(new PersonByAgeFilterSpec(20));
_personRepository.GetFilter(filterByNameAndAge);
Thus, you can connect and combine filters as much as you like. At the moment, you can connect filters using AND, Or, wrap filters in brackets, add a Not condition to filters
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- LinqKit (>= 1.2.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|