{"id":23704994,"url":"https://github.com/skarllot/expressions","last_synced_at":"2025-09-03T09:32:14.557Z","repository":{"id":136204100,"uuid":"603735344","full_name":"skarllot/Expressions","owner":"skarllot","description":"Provides base for specifications to a DDD model","archived":false,"fork":false,"pushed_at":"2025-08-31T13:55:53.000Z","size":2129,"stargazers_count":5,"open_issues_count":28,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-08-31T15:35:29.149Z","etag":null,"topics":["database","ef-core","martendb","query","repository","specification"],"latest_commit_sha":null,"homepage":"https://fgodoy.me/Expressions/","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/skarllot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["skarllot"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2023-02-19T12:31:05.000Z","updated_at":"2025-07-18T09:59:40.000Z","dependencies_parsed_at":"2023-09-30T17:36:44.238Z","dependency_job_id":"96d7ec36-73ce-4c1f-a87a-6c8307438ca8","html_url":"https://github.com/skarllot/Expressions","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/skarllot/Expressions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skarllot%2FExpressions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skarllot%2FExpressions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skarllot%2FExpressions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skarllot%2FExpressions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skarllot","download_url":"https://codeload.github.com/skarllot/Expressions/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skarllot%2FExpressions/sbom","scorecard":{"id":651414,"data":{"date":"2025-08-19T17:39:19Z","repo":{"name":"github.com/skarllot/Expressions","commit":"6a82265184ac13606c1f64a73536e461ec5e613e"},"scorecard":{"version":"v5.2.1","commit":"ab2f6e92482462fe66246d9e32f642855a691dc1"},"score":8.5,"checks":[{"name":"Code-Review","score":-1,"reason":"Found no human activity in the last 30 changesets","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#binary-artifacts"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: RenovateBot: .github/renovate.json:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dependency-update-tool"}},{"name":"Maintained","score":10,"reason":"14 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":10,"reason":"GitHub workflow tokens follow principle of least privilege","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:38","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:39","Warn: jobLevel 'contents' permission set to 'write': .github/workflows/create-tag.yml:19","Info: topLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:30","Info: topLevel 'contents' permission set to 'read': .github/workflows/create-tag.yml:12","Info: topLevel 'contents' permission set to 'read': .github/workflows/dependency-review.yml:13","Info: topLevel 'contents' permission set to 'read': .github/workflows/docs.yml:12","Info: topLevel 'contents' permission set to 'read': .github/workflows/dotnet.yml:19","Info: topLevel 'contents' permission set to 'read': .github/workflows/mutation-test.yml:21","Info: topLevel 'contents' permission set to 'read': .github/workflows/package.yml:14","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:18"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#token-permissions"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#security-policy"}},{"name":"Pinned-Dependencies","score":9,"reason":"dependency not pinned by hash detected -- score normalized to 9","details":["Warn: nugetCommand not pinned by hash: samples/Helpdesk.Relational/Dockerfile:10: pin your dependecies by either enabling central package management (https://learn.microsoft.com/nuget/consume-packages/Central-Package-Management) or using a lockfile (https://learn.microsoft.com/nuget/consume-packages/package-references-in-project-files#locking-dependencies)","Info:  27 out of  27 GitHub-owned GitHubAction dependencies pinned","Info:  11 out of  11 third-party GitHubAction dependencies pinned","Info:   4 out of   4 containerImage dependencies pinned","Info:   3 out of   4 nugetCommand dependencies pinned","Info:   2 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":5,"reason":"badge detected: Passing","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#cii-best-practices"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#signed-releases"}},{"name":"SAST","score":10,"reason":"SAST tool is run on all commits","details":["Info: SAST configuration detected: CodeQL","Info: all commits (30) are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":4,"reason":"6 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-67mh-4wv8-2f99","Warn: Project is vulnerable to: GHSA-5mfx-4wcx-rv27","Warn: Project is vulnerable to: GHSA-m5vv-6r4h-3vj9","Warn: Project is vulnerable to: GHSA-wvxc-855f-jvrv","Warn: Project is vulnerable to: GHSA-59j7-ghrg-fj52","Warn: Project is vulnerable to: GHSA-447r-wph3-92pm"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#vulnerabilities"}},{"name":"Branch-Protection","score":8,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Info: 'branch protection settings apply to administrators' is required to merge on branch 'main'","Info: 'stale review dismissal' is required to merge on branch 'main'","Warn: required approving review count is 1 on branch 'main'","Info: codeowner review is required on branch 'main'","Info: 'last push approval' is required to merge on branch 'main'","Info: 'up-to-date branches' is required to merge on branch 'main'","Info: status check found to merge onto on branch 'main'","Info: PRs are required in order to make changes on branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/package.yml:17"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#packaging"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#fuzzing"}},{"name":"Contributors","score":-1,"reason":"internal error: Client.Repositories.ListContributors: error during contributorsHandler.setup: error during ParseFile: line 1: unexpected character '﻿' at position 1","details":null,"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#contributors"}},{"name":"CI-Tests","score":10,"reason":"30 out of 30 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/ab2f6e92482462fe66246d9e32f642855a691dc1/docs/checks.md#ci-tests"}}]},"last_synced_at":"2025-08-21T13:35:56.528Z","repository_id":136204100,"created_at":"2025-08-21T13:35:56.528Z","updated_at":"2025-08-21T13:35:56.528Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273423142,"owners_count":25103140,"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","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["database","ef-core","martendb","query","repository","specification"],"created_at":"2024-12-30T14:06:53.408Z","updated_at":"2025-09-03T09:32:14.126Z","avatar_url":"https://github.com/skarllot.png","language":"C#","funding_links":["https://github.com/sponsors/skarllot"],"categories":[],"sub_categories":[],"readme":"# Raiqub Expressions\n\n_Raiqub.Expressions is a library that provides abstractions for creating specifications and query strategies using LINQ expressions. It also supports querying and writing to databases using various providers._\n\n[![Build status](https://github.com/skarllot/Expressions/actions/workflows/dotnet.yml/badge.svg?branch=main)](https://github.com/skarllot/Expressions/actions)\n[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/skarllot/Expressions/badge)](https://securityscorecards.dev/viewer/?uri=github.com/skarllot/Expressions)\n[![Code coverage](https://codecov.io/gh/skarllot/Expressions/branch/main/graph/badge.svg)](https://codecov.io/gh/skarllot/Expressions)\n[![Mutation testing badge](https://img.shields.io/endpoint?style=flat\u0026url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fskarllot%2FExpressions%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/skarllot/Expressions/main)\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://raw.githubusercontent.com/skarllot/Expressions/master/LICENSE)\n\n[🏃 Quickstart](#quickstart) \u0026nbsp; | \u0026nbsp; [📖 Documentation](https://fgodoy.me/Expressions/) \u0026nbsp; | \u0026nbsp; [🔄 Migration](https://fgodoy.me/Expressions/migration-guide.html)\n\n\u003chr /\u003e\n\n## Features\n* Easily define and compose specifications to encapsulate business rules\n* Create custom query strategies for flexible and efficient data retrieval\n* Simplify database operations by using consistent abstractions\n* Seamlessly integrate with Entity Framework Core for database interactions\n* Utilize Marten providers for a NoSQL document database experience\n* Built with .NET Standard 2.0, 2.1, and .NET 6.0\n\n## NuGet Packages\n* [![NuGet](https://buildstats.info/nuget/Raiqub.Expressions)](https://www.nuget.org/packages/Raiqub.Expressions/) **Raiqub.Expressions**: provides abstractions for creating specifications\n* [![NuGet](https://buildstats.info/nuget/Raiqub.Expressions.Reading)](https://www.nuget.org/packages/Raiqub.Expressions.Reading/) **Raiqub.Expressions.Reading**: provides abstractions for creating query strategies and query sessions. Defines the `IDbQuerySession` and `IDbQuerySessionFactory` interfaces for querying from the database\n* [![NuGet](https://buildstats.info/nuget/Raiqub.Expressions.Writing)](https://www.nuget.org/packages/Raiqub.Expressions.Writing/) **Raiqub.Expressions.Writing**: provides abstractions for creating write sessions and performing write operations. Defines the `IDbSession` and `IDbSessionFactory` interfaces for writing to the database\n* [![NuGet](https://buildstats.info/nuget/Raiqub.Expressions.EntityFrameworkCore)](https://www.nuget.org/packages/Raiqub.Expressions.EntityFrameworkCore/) **Raiqub.Expressions.EntityFrameworkCore**: implements sessions and factories using Entity Framework Core. Ideal for integrating with Entity Framework Core for database access\n* [![NuGet](https://buildstats.info/nuget/Raiqub.Expressions.Marten)](https://www.nuget.org/packages/Raiqub.Expressions.Marten/) **Raiqub.Expressions.Marten**: implements sessions and factories using Marten library. Perfect for leveraging Marten's NoSQL document database capabilities\n\n## Documentation\nThis README aims to give a quick overview of some Raiqub Expressions features. For deeper detail of available features, be sure also to check out [Documentation Page](https://fgodoy.me/Expressions/).\n\n## Prerequisites\nBefore you begin, you'll need the following:\n\n* .NET Standard 2.0 or 2.1, or .NET Core 6.0 installed on your machine\n* An IDE such as Visual Studio, Visual Studio Code, or JetBrains Rider\n* If you plan to use the reading package, have a database available for querying. If you intend to use the writing package, ensure you have a writable database to perform write operations\n\n## Quickstart\n\nTo use Raiqub.Expressions in your project, follow these steps:\n\n### Entity Framework Core\n\n1. Install the required NuGet package(s) for the database provider you'll be using, such as **\\`Microsoft.EntityFrameworkCore.SqlServer\\`**\n\n2. Install the **\\`Raiqub.Expressions.EntityFrameworkCore\\`** NuGet package\n\n3. Register your DbContext by using **\\`AddDbContextFactory\\`** extension method\n\n    ```csharp\n    services.AddDbContextFactory\u003cYourDbContext\u003e();\n    ```\n\n4. Register the session and session factories using the following extension method:\n\n    ```csharp\n    services.AddEntityFrameworkExpressions()\n        .AddSingleContext\u003cYourDbContext\u003e();\n    ```\n\n### Marten\n\n1. Install the **\\`Marten\\`** NuGet package\n\n2. Install the **\\`Raiqub.Expressions.Marten\\`** NuGet package\n\n3. Register the session and session factories using the following extension method:\n\n    ```csharp\n    services.AddMartenExpressions()\n        .AddSingleContext();\n    ```\n\n### Using\n\nInject the appropriate session interface (`IDbQuerySession` for read sessions, `IDbSession` for read and write sessions) into your services, and use it read and write from/to database.\n\n```csharp\npublic class YourService\n{\n    private readonly IDbSession _dbSession;\n\n    public YourService(IDbSession dbSession)\n    {\n        _dbSession = dbSession;\n    }\n\n    // ...\n}\n```\nYou can also create specifications and query strategies. Here's an example of how to create a simple specification:\n\n```csharp\npublic class CustomerIsActive : Specification\u003cCustomer\u003e\n{\n    public override Expression\u003cFunc\u003cCustomer, bool\u003e\u003e ToExpression()\n    {\n        return customer =\u003e customer.IsActive;\n    }\n}\n```\nAnd here's an example of how to use the specification:\n\n```csharp\n// Assuming 'session' is of type IDbSession or IDbQuerySession and has been injected\nvar query = session.Query(new CustomerIsActive());\nvar customers = await query.ToListAsync();\n```\n\n## Contributing\n\nIf something is not working for you or if you think that the source file\nshould change, feel free to create an issue or Pull Request.\nI will be happy to discuss and potentially integrate your ideas!\n\n## License\n\nThis library is licensed under the [MIT License](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskarllot%2Fexpressions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskarllot%2Fexpressions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskarllot%2Fexpressions/lists"}