{"id":21428927,"url":"https://github.com/notcoffee418/dapperbulkqueries","last_synced_at":"2025-08-24T01:12:08.624Z","repository":{"id":87668857,"uuid":"497300582","full_name":"NotCoffee418/DapperBulkQueries","owner":"NotCoffee418","description":"Unofficial implementation for executing bulk INSERT, UPDATE and DELETE queries with Dapper for PostgreSQL and SQL Server.","archived":false,"fork":false,"pushed_at":"2024-09-29T23:30:11.000Z","size":51,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-13T01:22:45.648Z","etag":null,"topics":["bulk","dapper","dapper-extensions","postgresql","sql"],"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/NotCoffee418.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}},"created_at":"2022-05-28T11:40:19.000Z","updated_at":"2024-08-23T17:03:21.000Z","dependencies_parsed_at":"2025-07-14T10:33:02.323Z","dependency_job_id":"11a2c0cc-4e60-406c-994b-021729778d98","html_url":"https://github.com/NotCoffee418/DapperBulkQueries","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/NotCoffee418/DapperBulkQueries","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotCoffee418%2FDapperBulkQueries","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotCoffee418%2FDapperBulkQueries/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotCoffee418%2FDapperBulkQueries/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotCoffee418%2FDapperBulkQueries/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NotCoffee418","download_url":"https://codeload.github.com/NotCoffee418/DapperBulkQueries/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotCoffee418%2FDapperBulkQueries/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271778236,"owners_count":24819265,"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-08-23T02:00:09.327Z","response_time":69,"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":["bulk","dapper","dapper-extensions","postgresql","sql"],"created_at":"2024-11-22T22:15:15.382Z","updated_at":"2025-08-24T01:12:08.597Z","avatar_url":"https://github.com/NotCoffee418.png","language":"C#","readme":"# DapperBulkQueries\n\n[![Nuget](https://img.shields.io/nuget/v/DapperBulkQueries.Npgsql?style=for-the-badge \"Nuget\")](https://www.nuget.org/packages/DapperBulkQueries.Npgsql/)\n\nUnofficial implementation for executing bulk INSERT, UPDATE and DELETE queries with Dapper for PostgreSQL.\n\n## Getting Started\n\n### Install the NuGet package\n\nYou can find the nuget package in the visual studio package manager or [here](https://www.nuget.org/packages/DapperBulkQueries.Npgsql/).\n\nIn a Usings.cs file, add the following to enable the package:\n\n```csharp\n// Add this to Usings.cs\nglobal using DapperBulkQueries.Npgsql;\n// Or add the using statement to every file where you intend to use \nusing DapperBulkQueries.Npgsql;\n```\n\n### Demo model\nFor the purposes of this demonstration, we will start off with the following:\n**SQL Table:**\n\n```sql\nCREATE TABLE TestTable (\n    Id bigserial PRIMARY KEY,\n    TextCol character varying,\n    NumberCol numeric,\n    BoolCol boolean);\n```\n\n**Corresponding class:**\n\n```csharp\npublic class TestTable\n{\n    public long Id { get; set; }\n    public string TextCol { get; set; }\n    public decimal NumberCol { get; set; }\n    public bool BoolCol { get; set; }\n}\n```\nI'll also assume you have a method to create and open an Npgsql connection.\n\n### Bulk Insert\n\n\n```csharp\n// First we generate some data that we intend to insert.\n// Optionally without specifying the ID as the `bigserial` datatype takes care of that.\nList\u003cTestTable\u003e insertData = new()\n{\n    new() {\n        TextCol = \"aaa\",\n        NumberCol = 1.23m,\n        BoolCol = true },\n    new() {\n        TextCol = \"bbb\",\n        NumberCol = 4.56m,\n        BoolCol = false },\n    new() {\n        TextCol = \"ccc\",\n        NumberCol = 7m,\n        BoolCol = true }\n};\n\n// We need to manually specify the column which we would like to insert\nList\u003cstring\u003e relevantColumns = new() { \"TextCol\", \"NumberCol\", \"BoolCol\" };\n\n// Then we need to specify the name of the table we're inserting to\nstring tableName = \"TestData\";\n\n// And finally we can execute the query like so:\nNpgsqlConnection conn = await GetOpenConnection();\nawait conn.ExecuteBulkInsertAsync(\n    tableName,\n    insertData,\n    relevantColumns);\n```\n\n### Bulk Delete\n```csharp\n// When bulk deleting we have a single selector column, \n// and anything containing any of the specified values will be deleted.\nvar valuesOfRowsToDelete = new List\u003cstring\u003e() { \"aaa\", \"ccc\" };\nawait conn.ExecuteBulkDeleteAsync(\n    tableName, \n    \"TextCol\", // Selector column\n    valuesOfRowsToDelete);\n\n```\n\n### Bulk Update\n```csharp\n// Updated version of first and second\nvar updateData = new List\u003cTestTable\u003e()\n{\n    new TestTable() { \n        Id = 1, // Explicitly add ID, since we'll be filtering on this\n        TextCol = \"Updated first\", \n        NumberCol = 5, \n        BoolCol = true },\n    new TestTable() { \n        Id = 2,\n        TextCol = \"Updated second\",\n        NumberCol = 6, \n        BoolCol = false }\n};\n\n// With updating we can have multiple selectors. \n// Meaning, all selector values must match before a row is affected\n// eg. Update WHERE Id AND BoolCol match\nvar selectors = new List\u003cstring\u003e() { \"Id\", \"BoolCol\" };\n\n// We also need to define which properties should be updated.\nvar propertiesToUpdate = new List\u003cstring\u003e() { \"TextCol\", \"NumberCol\" };\n\n// Finally we can execute the update like so\nawait conn.ExecuteBulkUpdateAsync(\n    tableName,\n    updateData,\n    selectors,\n    propertiesToUpdate\n);\n```\n\n### Calculated Properties\nYou may not always want the exact property value to be taken from the class.  \nFor instance, if you have a property, which is a class containing an ID which references another table.  \nA solution for this is provided in this package through calculated properties.\n\nLet's redefine our TestTable class to contain such a property\n```csharp\npublic class AnotherTable\n{\n    public long Id { get; set; }\n    public string Name { get; set; }\n}\npublic class TestTable\n{\n    public long Id { get; set; }\n    public bool BoolCol { get; set; }\n    \n    public AnotherTable Another { get; set; }\n}\n```\n\nTo insert this we can make use of calculated properties, which take the shape of \n```csharp\n// Dictionary key string: property name\n// Function input T: in the example would be an instance of TestTable\n// Function output object: the value that should be inserted in the database\nDictionary\u003cstring, Func\u003cT, object\u003e\u003e\n```\n\nThese override reading plain class properties if a property has a column name in the dictionary.  \n**NOTE:** Properties should still also be defined in the propertyNames list for it to be included.\n\nExample usage:\n```csharp\nList\u003cstring\u003e relevantColumns = new() { \n    \"TextCol\", \"NumberCol\", \"AnotherId\" };\n\n// Then we need to specify the name of the table we're inserting to\nstring tableName = \"TestData\";\n\n// Define the calculated properties dictionary\nDictionary\u003cstring, Func\u003cTestTable, object\u003e\u003e calculatedProperties = new()\n{\n    { \"AnotherId\", t =\u003e t.Another.Id }\n};\n\n// And finally we can execute the query like so:\nNpgsqlConnection conn = await GetOpenConnection();\nawait conn.ExecuteBulkInsertAsync(\n    tableName,\n    insertData,\n    relevantColumns,\n    calculatedProperties);\n```","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotcoffee418%2Fdapperbulkqueries","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnotcoffee418%2Fdapperbulkqueries","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotcoffee418%2Fdapperbulkqueries/lists"}