{"id":17339636,"url":"https://github.com/fiseni/queryspecification","last_synced_at":"2025-10-12T19:14:39.711Z","repository":{"id":56678502,"uuid":"279033610","full_name":"fiseni/QuerySpecification","owner":"fiseni","description":"A .NET library for building query specifications.","archived":false,"fork":false,"pushed_at":"2024-11-08T10:58:06.000Z","size":1918,"stargazers_count":51,"open_issues_count":0,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-02T21:52:01.119Z","etag":null,"topics":["efcore","pozitron","queryspecification","specification"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fiseni.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-12T09:38:56.000Z","updated_at":"2025-01-04T14:55:20.000Z","dependencies_parsed_at":"2024-09-06T03:15:47.930Z","dependency_job_id":"c855309e-f24f-4f1f-b246-b5e35cec242a","html_url":"https://github.com/fiseni/QuerySpecification","commit_stats":{"total_commits":237,"total_committers":1,"mean_commits":237.0,"dds":0.0,"last_synced_commit":"b876966f7e91b287f4c996d236905ac10b86ee3a"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiseni%2FQuerySpecification","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiseni%2FQuerySpecification/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiseni%2FQuerySpecification/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fiseni%2FQuerySpecification/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fiseni","download_url":"https://codeload.github.com/fiseni/QuerySpecification/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247423515,"owners_count":20936626,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["efcore","pozitron","queryspecification","specification"],"created_at":"2024-10-15T15:42:28.298Z","updated_at":"2025-10-12T19:14:34.689Z","avatar_url":"https://github.com/fiseni.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg align=\"left\" src=\"pozitronlogo.png\" width=\"120\" height=\"120\"\u003e\n\n\u0026nbsp; [![NuGet](https://img.shields.io/nuget/v/Pozitron.QuerySpecification.svg)](https://www.nuget.org/packages/Pozitron.QuerySpecification)\n\n\u0026nbsp; [![Full Build](https://github.com/fiseni/QuerySpecification/actions/workflows/build.yml/badge.svg)](https://github.com/fiseni/QuerySpecification/actions/workflows/build.yml)\n\n\u0026nbsp; [![Coverage](https://queryspecification.fiseni.com/badge_combined.svg)](https://queryspecification.fiseni.com)\n\n---\n\nA .NET library for building query specifications.\n- [Pozitron.QuerySpecification](https://www.nuget.org/packages/Pozitron.QuerySpecification)\n  A base package containing the core functionality, in-memory evaluators, and validators.\n- [Pozitron.QuerySpecification.EntityFrameworkCore](https://www.nuget.org/packages/Pozitron.QuerySpecification.EntityFrameworkCore)\n  An `EntityFramework Core` plugin to the base package. It contains EF specific evaluators.\n\n## Getting Started\n\nAn extended list of features (in-memory collection evaluations, validations, repositories, extensions, etc.) will be soon available in the Wiki. Below are listed some basic and common usages.\n\n### Creating and consuming specifications\n\nCreate your specifications by inheriting from the `Specification\u003cT\u003e` class, and use the `Query` builder in the constructor to define your conditions.\n\n```csharp\npublic class CustomerSpec : Specification\u003cCustomer\u003e\n{\n  public CustomerSpec(int age, string nameTerm)\n  {\n    Query\n      .Where(x =\u003e x.Age \u003e= age)\n      .Like(x =\u003e x.Name, $\"%{nameTerm}%\")\n      .Include(x =\u003e x.Addresses)\n          .ThenInclude(x =\u003e x.Contact)\n      .OrderBy(x =\u003e x.Id)\n          .ThenBy(x =\u003e x.Name)\n      .Skip(10)\n      .Take(10)\n      .AsSplitQuery();\n  }\n}\n```\n\nApply the specification to `DbSet\u003cT\u003e` or `IQueryable\u003cT\u003e` source.\n\n```csharp\nvar spec = new CustomerSpec(30, \"Customer\");\n\nList\u003cCustomer\u003e result = await _context\n    .Customers\n    .WithSpecification(spec)\n    .ToListAsync();\n```\n\n### Projections\n\nThe specification can be used to project the result into a different type. Inherit from `Specification\u003cT, TResult\u003e` class, where TResult is the type you want to project into. This offers strongly typed experience in the builder and during the evaluation.\n\n```csharp\npublic class CustomerDtoSpec : Specification\u003cCustomer, CustomerDto\u003e\n{\n  public CustomerDtoSpec(int age, string nameTerm)\n  {\n    Query\n      .Where(x =\u003e x.Age \u003e= age)\n      .Like(x =\u003e x.Name, $\"%{nameTerm}%\")\n      .OrderBy(x =\u003e x.Name)\n      .Select(x =\u003e new CustomerDto(x.Id, x.Name));\n  }\n}\n```\n\nApply the specification to `DbSet\u003cT\u003e` or `IQueryable\u003cT\u003e` source.\n\n```csharp\nvar spec = new CustomerDtoSpec(30, \"Customer\");\n\nList\u003cCustomerDto\u003e result = await _context\n    .Customers\n    .WithSpecification(spec)\n    .ToListAsync();\n```\n\n### Pagination\n\nThe library defines a convenient `ToPagedResult` extension method that returns a detailed paged result.\n\n```csharp\nvar spec = new CustomerDtoSpec(1, \"Customer\");\nvar pagingFilter = new PagingFilter\n{\n    Page = 1,\n    PageSize = 2\n};\n\nPagedResult\u003cCustomerDto\u003e result = await _context\n    .Customers\n    .WithSpecification(spec)\n    .ToPagedResultAsync(pagingFilter);\n```\n\nThe `PagedResult\u003cT\u003e` is serializable and contains a detailed pagination information and the data.\n\n```json\n{\n  \"Pagination\": {\n    \"TotalItems\": 100,\n    \"TotalPages\": 50,\n    \"PageSize\": 2,\n    \"Page\": 1,\n    \"StartItem\": 1,\n    \"EndItem\": 2,\n    \"HasPrevious\": false,\n    \"HasNext\": true\n  },\n  \"Data\": [\n    {\n      \"Id\": 1,\n      \"Name\": \"Customer 1\"\n    },\n    {\n      \"Id\": 2,\n      \"Name\": \"Customer 2\"\n    }\n  ]\n}\n```\n\n## Benchmarks\n\nIn version 11, we refactored and rebuilt the internals from the ground up. The new version reduces the memory footprint drastically. The overhead of the library is now negligible and statistically insignificant. Here are the benchmark results of `ToQueryString()` for various queries. Refer to the [Benchmarks](https://github.com/fiseni/QuerySpecification/tree/main/tests/QuerySpecification.Benchmarks/Benchmarks) project for more benchmarks.\n\nType:\n- 0 -\u003e Empty\n- 1 -\u003e Single Where clause\n- 2 -\u003e Where and OrderBy\n- 3 -\u003e Where, Order chain, Include chain, Flag (AsNoTracking)\n- 4 -\u003e Where, Order chain, Include chain, Like, Skip, Take, Flag (AsNoTracking)\n\n| Method | Type | Mean      | Error    | StdDev   | Ratio | Gen0    | Gen1   | Allocated | Alloc Ratio |\n|------- |----- |----------:|---------:|---------:|------:|--------:|-------:|----------:|------------:|\n| EFCore | 0    |  81.55 us | 0.686 us | 0.608 us |  1.00 | 10.0098 | 0.9766 |  82.54 KB |        1.00 |\n| Spec   | 0    |  78.18 us | 0.472 us | 0.441 us |  0.96 | 10.0098 | 0.9766 |  82.53 KB |        1.00 |\n|        |      |           |          |          |       |         |        |           |             |\n| EFCore | 1    |  92.62 us | 0.350 us | 0.310 us |  1.00 | 10.2539 | 0.9766 |  84.77 KB |        1.00 |\n| Spec   | 1    |  92.92 us | 0.252 us | 0.236 us |  1.00 | 10.2539 | 0.9766 |  84.84 KB |        1.00 |\n|        |      |           |          |          |       |         |        |           |             |\n| EFCore | 2    |  95.48 us | 0.654 us | 0.580 us |  1.00 | 10.2539 | 0.9766 |  86.03 KB |        1.00 |\n| Spec   | 2    |  98.36 us | 0.775 us | 0.687 us |  1.03 | 10.2539 | 0.4883 |  86.12 KB |        1.00 |\n|        |      |           |          |          |       |         |        |           |             |\n| EFCore | 3    | 106.62 us | 0.684 us | 0.606 us |  1.00 | 10.7422 | 0.4883 |  90.35 KB |        1.00 |\n| Spec   | 3    | 109.56 us | 0.700 us | 0.655 us |  1.03 | 10.7422 | 0.4883 |  90.64 KB |        1.00 |\n|        |      |           |          |          |       |         |        |           |             |\n| EFCore | 4    | 147.47 us | 0.619 us | 0.483 us |  1.00 | 13.1836 | 0.9766 | 110.78 KB |        1.00 |\n| Spec   | 4    | 150.82 us | 0.538 us | 0.449 us |  1.02 | 13.1836 | 0.9766 | 111.32 KB |        1.00 |\n\n## Give a Star! :star:\nIf you like or are using this project please give it a star. Thanks!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffiseni%2Fqueryspecification","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffiseni%2Fqueryspecification","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffiseni%2Fqueryspecification/lists"}