{"id":24370362,"url":"https://github.com/alnkesq/duckdbsharp","last_synced_at":"2025-04-10T17:53:41.024Z","repository":{"id":198034900,"uuid":"682068456","full_name":"alnkesq/DuckDbSharp","owner":"alnkesq","description":"Bidirectional interoperability between DuckDB and .NET","archived":false,"fork":false,"pushed_at":"2024-02-21T14:52:33.000Z","size":204,"stargazers_count":9,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-03-27T06:03:35.190Z","etag":null,"topics":["dotnet","duckdb","parquet","sql"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alnkesq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2023-08-23T11:20:14.000Z","updated_at":"2024-06-28T15:28:47.668Z","dependencies_parsed_at":"2024-02-21T16:11:28.719Z","dependency_job_id":"47a516c0-d52b-408a-aa9d-2497da5268e9","html_url":"https://github.com/alnkesq/DuckDbSharp","commit_stats":null,"previous_names":["alnkesq/duckdbsharp"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alnkesq%2FDuckDbSharp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alnkesq%2FDuckDbSharp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alnkesq%2FDuckDbSharp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alnkesq%2FDuckDbSharp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alnkesq","download_url":"https://codeload.github.com/alnkesq/DuckDbSharp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248262434,"owners_count":21074308,"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":["dotnet","duckdb","parquet","sql"],"created_at":"2025-01-19T04:34:31.270Z","updated_at":"2025-04-10T17:53:41.002Z","avatar_url":"https://github.com/alnkesq.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![protobuf-net](https://img.shields.io/nuget/v/DuckDbSharp.svg)](https://www.nuget.org/packages/DuckDbSharp/)\n\n# DuckDbSharp\n\nDuckDbSharp is a bidirectional interoperability layer between [DuckDB](https://github.com/duckdb/duckdb) and .NET.\n\nFeatures\n- Support for **deeply nested** structures and lists\n- Expose .NET methods/collections as **table UDFs**, or as **scalar functions**\n- Execute DuckDB queries from .NET\n- Generates **static types** from SQL (incl. field nullness detection)\n- Dynamic results are supported as well (as dynamic assemblies/types)\n- **Performance-oriented** with minimal allocations\n- Support for both normal and `[Flags]` enums\n- Native AOT support\n- Pass .NET collections as SQL parameters (either as array or as table)\n- Results are streamed as `IEnumerable\u003c\u003e`\n- Write DuckDB loadable extensions in C# (work in progress)\n\nNotes:\n- This is **not** an ADO.NET (System.Data) provider\n  - Rationale: ADO.NET is flat-table oriented (sublists/subfields are not first class citizens, despite these being probably among the best features of DuckDB).\n  - Additionally, ADO.NET is very unergonomic to use unless you add an ORM on top of it. Most existing ORMs however don't work well with sublists/subfields. This library deserializes/serializes directly on top of CLR POCO objects, and can generate (and keep up to date) the type definitions for a better IDE experience.\n\n## Usage\n\n### Calling DuckDB from .NET (auto-generated types)\n```sql\n-- my_query.sql\nSELECT\n    42 AS column1,\n    [1, 2, 3] AS column2,\n    [{a: 1, b: 2}] as column3\n```\n\n```csharp\nforeach (var user in db.ExecuteQuery_my_query())\n{\n    // \"user\" has an auto-generated type with all the fields and sub-fields of the SQL query above.\n}\n```\nSee [detailed instructions](#getting-started) below.\n\n### Calling DuckDB from .NET (inline sql)\n```csharp\nusing var db = ThreadSafeTypedDuckDbConnection.CreateInMemory();\nforeach (var user in db.Execute\u003cUser\u003e(\"select * from user\"))\n{\n    \n}\n```\n\nYou can also use value tuples (`Execute\u003c(string A, int B)\u003e(\"select 'a', 42\")`), but keep in mind that only column order matters, since tuple member names are erased at runtime.\n\n### Calling .NET from DuckDB\n```csharp\n[DuckDbFunction]\npublic static IEnumerable\u003cUser\u003e GetUsers(string country) { /*...*/ }\n```\n\n```sql\nSELECT * FROM GetUsers('US')\n```\n\n\n## Getting started\n- Add a reference to `DuckDbSharp`\n- Create a [queries](https://github.com/alnkesq/DuckDbSharp/tree/main/tests/DuckDbSharp.Example/queries) directory with the `.sql` queries you want to be able to call from .NET\n   - File name must be: `ReturnType query_name(paramtype1, paramtype2).sql`\n   - If `ReturnType` is not specified, a type will be automatically generated based on the SQL schema of the result.\n   - If your query is parameterized, specify the types of the parameters (e.g. `string` or `long`). Otherwise, parens are unnecessary.\n- Call `GenerateCSharpTypes` as shown in the [example](https://github.com/alnkesq/DuckDbSharp/blob/main/tests/DuckDbSharp.Example/Program.cs), and run.\n- Start using the now generated extension methods of `TypedDuckDbConnectionBase` (one for each query).\n- Remember to commit the generated files as well. This is very important in order to be able to recompile old versions of the repository.\n\n\n## Benchmarks\nTime to read ~100,000 rows of Northwind customers. In all 4 cases, the final result is a `List\u003cCustomer\u003e`.\n|                        Library |     Mean |   Error |  StdDev | Description\n|------------------------------ |---------:|--------:|--------:|--------------\n| **DuckDbSharp (this project)** | **145.4 ms** | 2.63 ms | 2.46 ms |SELECT * FROM customer\n| DuckDB.NET + Dapper | 177.2 ms | 2.88 ms | 2.69 ms | SELECT * FROM customer\n| Protobuf-net | **131.3 ms** | 2.52 ms | 2.81 ms | Deserialize from MemoryStream of protos\n| Newtonsoft JSON | 241.7 ms | 2.93 ms | 2.60 ms | Deserialize from MemoryStream of JSON\n\nNote: while protobuf-net is slightly faster, its use cases is very different (serialization/deserialization only, with no query support)\n\n## Advanced features\n### Customizing (de)serialization\n- `[DuckDbInclude]` and `[DuckDbIgnore]` always take the precedence over other rules. In their absence, `[ProtoMember]` from protobuf-net is also taken into account. Otherwise, only public fields and properties are taken into account.\n- Enums are serialized as DuckDb enums, you can override this with `[DuckDbSerializeAs(typeof(string))]` or `[DuckDbSerializeAs(typeof(int))]` (or whatever their underlying type is).\n- `[Flags]` enums are always serialized as structs of booleans, one for each bit.\n- `[DuckDbDefaultValueIsNullish]` can be applied to structs, and it means that `default(SomeStruct)` should be represented as `NULL` in DuckDB.\n### Reading and writing parquets\n- You can use `DuckDbUtils.QueryParquet\u003cT\u003e()` and `DuckDbUtils.WriteParquet\u003cT\u003e()` to directly read/write `.parquet` files (no database required).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falnkesq%2Fduckdbsharp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falnkesq%2Fduckdbsharp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falnkesq%2Fduckdbsharp/lists"}