{"id":25290962,"url":"https://github.com/salixzs/dapper.cqrs","last_synced_at":"2026-04-30T10:06:24.859Z","repository":{"id":44960651,"uuid":"358666099","full_name":"salixzs/Dapper.Cqrs","owner":"salixzs","description":"Utilize CQRS approach with Dapper in easy and testable way.","archived":false,"fork":false,"pushed_at":"2025-12-21T15:26:29.000Z","size":1073,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-23T05:37:11.604Z","etag":null,"topics":["cqrs","dapper","database","nuget-packages","orm-extension"],"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/salixzs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-04-16T16:58:33.000Z","updated_at":"2025-12-21T15:26:33.000Z","dependencies_parsed_at":"2023-11-19T16:45:55.931Z","dependency_job_id":null,"html_url":"https://github.com/salixzs/Dapper.Cqrs","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/salixzs/Dapper.Cqrs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salixzs%2FDapper.Cqrs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salixzs%2FDapper.Cqrs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salixzs%2FDapper.Cqrs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salixzs%2FDapper.Cqrs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/salixzs","download_url":"https://codeload.github.com/salixzs/Dapper.Cqrs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salixzs%2FDapper.Cqrs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32460835,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T22:27:22.272Z","status":"online","status_checked_at":"2026-04-30T02:00:05.929Z","response_time":57,"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":["cqrs","dapper","database","nuget-packages","orm-extension"],"created_at":"2025-02-13T00:51:22.262Z","updated_at":"2026-04-30T10:06:24.837Z","avatar_url":"https://github.com/salixzs.png","language":"C#","funding_links":["https://www.buymeacoffee.com/salixzs"],"categories":[],"sub_categories":[],"readme":"# Dapper.Cqrs\n\n\u003cimg align=\"left\" src=\"DapperCQRS.png\"\u003e\n\nPackages provides ability to use [CQRS (Command Query Responsibility Segregation)](https://martinfowler.com/bliki/CQRS.html) pattern for database data reading (Queries) or its modification (Commands). It includes ambient connection and transaction handling, so after easy set-up, developers are only required to write Query and Command classes which usually are database SQL statements, wrapped in separate classes, with a little bit of parameter handling (business as usual).\n\nPackage uses [Dapper](https://stackexchange.github.io/Dapper/) - a simple object mapper for .Net built by StackOverflow developers and is one of the most performing ORMs in .Net landscape (if not fastest).\n\nProject was influenced by another repository - [UPNXT-Dapper-cqrs](https://github.com/upnxt/upnxt-dapper-cqrs). Solution is separating concerns into Abstractions (no dependencies), Database-specific and Testing helpers to be used in more architecturally utilizable way with [practical developer usage ease](https://github.com/salixzs/Dapper.Cqrs/wiki/Productivity) and ability to [validate \"magic string queries\"](https://github.com/salixzs/Dapper.Cqrs/wiki/QueryTesting) against database to avoid runtime fails due to database structural changes not followed in code.\n\nRepo containing actual usage [sample project](https://github.com/salixzs/Dapper.Cqrs/wiki/AspNet5ApiSample) and Visual Studio [item templates](https://github.com/salixzs/Dapper.Cqrs/wiki/Productivity#provided-templates) for most of development needs.\n\nApproach is succesfully used in huge project (\u003e3M code lines) and database of 200 tables with ~10TB of data.\n\nPackages are targeting .Net Standard 2.0\n\n| Package | NuGet | Build |  Code Coverage | Downloads |\n| ------- | ----- | ----- | -------------- | --------- |\n| Dapper.CQRS.Abstractions | [![Nuget](https://img.shields.io/nuget/v/Salix.Dapper.Cqrs.Abstractions?logo=nuget\u0026logoColor=lightblue\u0026style=plastic)](https://www.nuget.org/packages/Salix.Dapper.Cqrs.Abstractions) | ![Azure DevOps Build ](https://img.shields.io/azure-devops/build/SmartDance/45bc2cc0-bce1-4cac-a1d8-ba3f243940a6/4?style=plastic\u0026logo=azuredevops\u0026logoColor=blue) | [![Azure DevOps coverage](https://img.shields.io/azure-devops/coverage/SmartDance/GitHubProjects/4?color=green\u0026logo=azuredevops\u0026logoColor=blue\u0026style=plastic)](https://dev.azure.com/SmartDance/GitHubProjects/_build?definitionId=4) | ![Nuget](https://img.shields.io/nuget/dt/Salix.Dapper.Cqrs.Abstractions?logo=nuget\u0026logoColor=lightblue\u0026style=plastic) |\n| Dapper.CQRS.MsSql | [![Nuget](https://img.shields.io/nuget/v/Salix.Dapper.Cqrs.MsSql?logo=nuget\u0026logoColor=lightblue\u0026style=plastic)](https://www.nuget.org/packages/Salix.Dapper.Cqrs.MsSql) | ![Azure DevOps Build ](https://img.shields.io/azure-devops/build/SmartDance/45bc2cc0-bce1-4cac-a1d8-ba3f243940a6/5?style=plastic\u0026logo=azuredevops\u0026logoColor=blue) | [![Azure DevOps coverage](https://img.shields.io/azure-devops/coverage/SmartDance/GitHubProjects/5?color=green\u0026logo=azuredevops\u0026logoColor=blue\u0026style=plastic)](https://dev.azure.com/SmartDance/GitHubProjects/_build?definitionId=5) | ![Nuget](https://img.shields.io/nuget/dt/Salix.Dapper.Cqrs.MsSql?logo=nuget\u0026logoColor=lightblue\u0026style=plastic) |\n| Dapper.CQRS.Testing.MsSql.xUnit | [![Nuget](https://img.shields.io/nuget/v/Salix.Dapper.Cqrs.MsSql.Testing.XUnit?logo=nuget\u0026logoColor=lightblue\u0026style=plastic)](https://www.nuget.org/packages/Salix.Dapper.Cqrs.MsSql.Testing.XUnit) | ![Azure DevOps Build ](https://img.shields.io/azure-devops/build/SmartDance/45bc2cc0-bce1-4cac-a1d8-ba3f243940a6/6?style=plastic\u0026logo=azuredevops\u0026logoColor=blue) | N/A | ![Nuget](https://img.shields.io/nuget/dt/Salix.Dapper.Cqrs.MsSql.Testing.XUnit?logo=nuget\u0026logoColor=lightblue\u0026style=plastic) |\n\n\u003e Detailed documentation is in [WIKI](https://github.com/salixzs/Dapper.Cqrs/wiki).\n\n# Usage\n\nWhen packages are added and set-up (see \"[Setup](https://github.com/salixzs/Dapper.Cqrs/wiki/Setup)\" in Wiki) - as application developer you need to do two things (besides writing tests).\n\n* Create `IQuery` (Data retrieval) or `ICommand` (Data modification) implementation classes based on provided base classes.\n* Inject `ICommandQueryContext` into your business logic class and use it to execute `IQuery` and `ICommand` classes against database engine. This is the only dependency required to work with database (Yeah, no more numerous repositories to depend upon!)\n\n## IQuery\nRequired to be able to read data from database. Create new class and implement its interface (used provided base class to partially do that):\n```csharp\npublic sealed class GetAllRecordsQuery : MsSqlQueryMultipleBase\u003cSampleData\u003e\n{\n    public override string SqlStatement =\u003e \"SELECT * FROM SampleDataTable\";\n}\n```\n\n\n## ICommand\nSimilar to Query above, but dedicated to data modification statements.\n```csharp\npublic sealed class SampleCreateCommand : MsSqlCommandBase\u003cint\u003e\n{\n    // Holds passed in object to be created as record in DB.\n    private readonly SampleData _sampleObject;\n    \n    // Constructor, getting object to be saved\n    public SampleCreateCommand(SampleData dbObject) =\u003e\n        _sampleObject = dbObject ?? throw new ArgumentNullException(nameof(dbObject), \"No data passed\");\n    \n    // Actual SQL statement to be executed.\n    // Here appended statement to get last autoincrement value from DB == inserted record ID.\n    public override string SqlStatement =\u003e @\"\n        INSERT INTO SampleTable (\n            Name\n        ) VALUES (\n            @Name\n        );SELECT CAST(SCOPE_IDENTITY() as int)\";\n\n    // Prepare object for Dapper to pass as parameters for SQL statement\n    public override object Parameters =\u003e _sampleObject;\n}\n```\n\n## Execution\n\nInject `ICommandQueryContext` into your business logic classes, which require to work with data in database.\n```csharp\npublic class SampleLogic : ISampleLogic\n{\n    private readonly ICommandQueryContext _db;\n    \n    // Constructor - yes, inject just this one (no more numerous repositories!)\n    public SampleLogic(ICommandQueryContext db) =\u003e _db = db;\n}\n```\n\nThen in this class methods you can use this injected object and use its methods with prepared `IQuery` and `ICommand` classes to do database calls.\n\n```csharp\n// Reading data (CancellationToken in optional parameter - can be omitted = CancellationToken.None)\npublic async Task\u003cIEnumerable\u003cSampleData\u003e\u003e GetAll(int refId, CancellationToken token) =\u003e \n    await _db.QueryAsync(new SampleQuery(refId), token);\n\n// Creating (saving) data (CancellationToken in optional parameter - can be omitted = CancellationToken.None)\npublic async Task\u003cint\u003e Create(SampleData dataObject, CancellationToken token) =\u003e \n    await _db.ExecuteAsync(new SampleCreateCommand(dataObject), token);\n```\n\n## Testability\nAs package uses interfaces for everything - it is easy to be mocked for isolation in pure unit-testing routines.\n\n`Testing` package includes prepared base classes and helpers to automatically find all Queries and Commands in your project and validate SQL statements in those against database for syntax validity. There are helpers for other testing needs, like compare DTO with database object and write/read tests.\n\nSee Sample project testing project for reference to such tests.\n\n\u003e Read more detailed documentation in [WIKI](https://github.com/salixzs/Dapper.Cqrs/wiki).\n\n\n### Like what I created?\n\u003ca href=\"https://www.buymeacoffee.com/salixzs\" target=\"_blank\"\u003e\u003cimg src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy Me A Coffee\" style=\"height: 32px !important;width: 146px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\" \u003e\u003c/a\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalixzs%2Fdapper.cqrs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsalixzs%2Fdapper.cqrs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalixzs%2Fdapper.cqrs/lists"}