DuckDB bindings for C#
dotnet add package DuckDB.NET.Data.Fullusing (var duckDBConnection = new DuckDBConnection("Data Source=file.db"))
{
duckDBConnection.Open();
using var command = duckDBConnection.CreateCommand();
command.CommandText = "CREATE TABLE integers(foo INTEGER, bar INTEGER);";
var executeNonQuery = command.ExecuteNonQuery();
command.CommandText = "INSERT INTO integers VALUES (3, 4), (5, 6), (7, 8);";
executeNonQuery = command.ExecuteNonQuery();
command.CommandText = "Select count(*) from integers";
var executeScalar = command.ExecuteScalar();
command.CommandText = "SELECT foo, bar FROM integers";
var reader = command.ExecuteReader();
PrintQueryResults(reader);
}
private static void PrintQueryResults(DbDataReader queryResult)
{
for (var index = 0; index < queryResult.FieldCount; index++)
{
var column = queryResult.GetName(index);
Console.Write($"{column} ");
}
Console.WriteLine();
while (queryResult.Read())
{
for (int ordinal = 0; ordinal < queryResult.FieldCount; ordinal++)
{
var val = queryResult.GetInt32(ordinal);
Console.Write(val);
Console.Write(" ");
}
Console.WriteLine();
}
}Use this workflow to build and publish Irion packages with bundled native DuckDB runtimes. The standard flow uses:
build/irion.versionas the single source of truth for the package versionscripts/irion-package.ps1to show/set/bump, check remote, build, pack and push
- Build DuckDB runtimes for
linux-x64andwin-x64. - Make sure the runtime archives are available as
win-x64.zipandlinux-x64.zip. - Set
DuckDbArtifactRootinDuckDB.NET.Bindings/Bindings.csprojto the folder/share containing those archives.
DuckDB.NET.Bindings/Bindings.csproj expects:
$(DuckDbArtifactRoot)/win-x64.zip
$(DuckDbArtifactRoot)/linux-x64.zip
Current version:
.\scripts\irion-package.ps1 -Command showSet explicit version:
.\scripts\irion-package.ps1 -Command set -Version 1.5.2.2Bump version in build/irion.version:
.\scripts\irion-package.ps1 -Command bump -Part prerelease # 1.4.4.0-alpha.1 -> 1.4.4.0-alpha.2
# .\scripts\irion-package.ps1 -Command bump -Part revision # 1.4.4.1 -> 1.4.4.2
# .\scripts\irion-package.ps1 -Command bump -Part build # 1.4.4.1 -> 1.4.5.0
# .\scripts\irion-package.ps1 -Command bump -Part minor # 1.4.4.1 -> 1.5.0.0
# .\scripts\irion-package.ps1 -Command bump -Part major # 1.4.4.1 -> 2.0.0.0Check latest published versions on the configured feed:
.\scripts\irion-package.ps1 -Command remote-show -NuGetSource "Repository"You can override package IDs if needed:
.\scripts\irion-package.ps1 -Command remote-show -NuGetSource "Repository" -DataPackageId "Irion.DuckDB.NET.Data.Full" -BindingsPackageId "Irion.DuckDB.NET.Bindings.Full".\scripts\irion-package.ps1 -Command build -p "NativeDownloadRetries=30","NativeDownloadRetryDelayMilliseconds=15000"The build command runs a full dotnet clean for both Irion projects before building.
.\scripts\irion-package.ps1 -Command packThe script reads build/irion.version, sets DUCKDB_VERSION_BUILD internally, and uses that value for:
/p:Version/p:FileVersion
NuGet package versions are normalized when the fourth segment is zero, so 1.5.0.0 becomes package version 1.5.0.
The script handles that automatically when it sets /p:PackageVersion and when it resolves the .nupkg filename for push.
Generated packages:
DuckDB.NET.Bindings/bin/Release/Irion.DuckDB.NET.Bindings.Full.<nuget-version>.nupkgDuckDB.NET.Data/bin/Release/Irion.DuckDB.NET.Data.Full.<nuget-version>.nupkg
if -PackageReleaseNotes or -PackageReleaseNotesFile are provided, the content is included in the generated .nupkg metadata and visible on NuGet.org.
.\scripts\irion-package.ps1 -Command pack -PackageReleaseNotes "New feature short description" -PackageReleaseNotesFile "RELEASE-NOTE.md".\scripts\irion-package.ps1 -Command push -NuGetSource "Repository" -ApiKey "az"After both packages are pushed successfully, the script creates a Git tag from build/irion.version
using the default format v<version> and pushes it to origin.
For example, 1.5.0.1 becomes v1.5.0.1.
To skip tagging during a retry:
.\scripts\irion-package.ps1 -Command push -NuGetSource "Repository" -ApiKey "az" -SkipTag.\scripts\irion-package.ps1 -Command packpush -NuGetSource "Repository" -ApiKey "az"$buildVersion = (Get-Content .\build\irion.version -Raw).Trim()
$parsedVersion = [Version]$buildVersion
$packageVersion = if ($parsedVersion.Revision -eq 0) { $parsedVersion.ToString(3) } else { $parsedVersion.ToString(4) }
$env:DUCKDB_VERSION_BUILD = $buildVersion
dotnet pack DuckDB.NET.Bindings/Bindings.csproj -c Release /p:BuildType=Full /p:Version=$buildVersion /p:FileVersion=$buildVersion /p:PackageVersion=$packageVersion
dotnet pack DuckDB.NET.Data/Data.csproj -c Release /p:BuildType=Full /p:Version=$buildVersion /p:FileVersion=$buildVersion /p:PackageVersion=$packageVersion
dotnet nuget push --source "Repository" --api-key az .\DuckDB.NET.Data\bin\Release\Irion.DuckDB.NET.Data.Full.$packageVersion.nupkg
dotnet nuget push --source "Repository" --api-key az .\DuckDB.NET.Bindings\bin\Release\Irion.DuckDB.NET.Bindings.Full.$packageVersion.nupkg
git tag "v$buildVersion"
git push origin "refs/tags/v$buildVersion"Quick checklist before publishing:
DuckDbArtifactRootpoints to the correct runtime artifacts.build/irion.versioncontains the final release version.- Both
dotnet packcommands completed successfully. - Both packages were pushed to the target feed.
git checkout v1.4.4
git fetch upstream --tags
git merge refs/tags/1.4.4
git push origin v1.4.4git checkout <target-branch>
git fetch upstream --tags
git merge refs/tags/<tag-version>
git push origin <target-branch>git log --oneline HEAD..refs/tags/<tag-version>To connect to MotherDuck:
using var duckDBConnection = new DuckDBConnection("DataSource=md:{your_database}?motherduck_token=ey...");If you want to build DuckDB extensions with C#, see Giorgi/DuckDB.ExtensionKit.
When debugging your project that uses DuckDB.NET library, you may get the following error: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. The error happens due to debugger interaction with the native memory. For a workaround check out Debugger Options mess up debugging session during Marshalling
Documentation is available at https://duckdb.net
If you encounter a bug with the library Create an Issue. Join the DuckDB dotnet channel for DuckDB.NET-related topics.
A big thanks to DuckDB Labs and AWS Open Source Software Fund for sponsoring the project!


