DuckDB.NET.Data.Full 2.0.0-preview.1

Prefix Reserved
This is a prerelease version of DuckDB.NET.Data.Full.
dotnet add package DuckDB.NET.Data.Full --version 2.0.0-preview.1
                    
NuGet\Install-Package DuckDB.NET.Data.Full -Version 2.0.0-preview.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="DuckDB.NET.Data.Full" Version="2.0.0-preview.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DuckDB.NET.Data.Full" Version="2.0.0-preview.1" />
                    
Directory.Packages.props
<PackageReference Include="DuckDB.NET.Data.Full" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add DuckDB.NET.Data.Full --version 2.0.0-preview.1
                    
#r "nuget: DuckDB.NET.Data.Full, 2.0.0-preview.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package DuckDB.NET.Data.Full@2.0.0-preview.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=DuckDB.NET.Data.Full&version=2.0.0-preview.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=DuckDB.NET.Data.Full&version=2.0.0-preview.1&prerelease
                    
Install as a Cake Tool

DuckDB.NET

DuckDB bindings for C#

GitHub Workflow Status Coveralls License Ko-Fi Discord

NuGet DuckDB.NET.Data NuGet DuckDB.NET.Bindings

NuGet DuckDB.NET.Data.Full NuGet DuckDB.NET.Bindings.Full

Project Icon

Usage

dotnet add package DuckDB.NET.Data.Full
using (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();
  }
}

MotherDuck

To connect to MotherDuck:

using var duckDBConnection = new DuckDBConnection("DataSource=md:{your_database}?motherduck_token=ey...");

DuckDB Extensions (C#)

If you want to build DuckDB extensions with C#, see Giorgi/DuckDB.ExtensionKit.

Known Issues

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

Documentation is available at https://duckdb.net

Support

If you encounter a bug with the library Create an Issue. Join the DuckDB dotnet channel for DuckDB.NET-related topics.

Contributors

Contributors

Sponsors

A big thanks to DuckLabs and AWS Open Source Software Fund for sponsoring the project!

DuckLabs

AWS

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (70)

Showing the top 5 NuGet packages that depend on DuckDB.NET.Data.Full:

Package Downloads
Kurrent.Quack

Package Description

UnifiedBlazor.Shared.DataAccess

UnifiedBlazor框架的DataAccess共享库

Kurrent.Surge.DuckDB

Package Description

DuckDB.InteractiveExtension

DuckDB support for Polyglot Notebooks

ShiftSoftware.ADP.SyncAgent

Package Description

GitHub repositories (13)

Showing the top 13 popular GitHub repositories that depend on DuckDB.NET.Data.Full:

Repository Stars
DapperLib/Dapper
Dapper - a simple object mapper for .Net
DotNetNext/SqlSugar
.Net aot ORM SqlServer ORM Mongodb ORM MySql 瀚高 Postgresql ORM DB2 Hana 高斯 Duckdb C# VB.NET Sqlite ORM Oracle ORM Mysql Orm 虚谷数据库 达梦 ORM 人大金仓 ORM 神通ORM C# ORM , C# ORM .NET ORM NET9 ORM .NET8 ORM ClickHouse ORM QuestDb ,TDengine ORM,OceanBase ORM,GaussDB ORM,Tidb ORM Object/Relational Mapping
dotnetcore/FreeSql
.NET aot orm, VB.NET/C# orm, Mysql/PostgreSQL/SqlServer/Oracle orm, Sqlite/Firebird/Clickhouse/DuckDB orm, 达梦/金仓/虚谷/翰高/高斯 orm, 神通 orm, 南大通用 orm, 国产 orm, TDengine orm, QuestDB orm, MsAccess orm.
linq2db/linq2db
Linq to database provider.
dotnet/interactive
.NET Interactive combines the power of .NET with many other languages to create notebooks, REPLs, and embedded coding experiences. Share code, explore data, write, and learn across your apps in ways you couldn't before.
mukunku/ParquetViewer
Simple Windows desktop application for viewing & querying Apache Parquet files
brianluft/sqlnotebook
SQL Notebook — Casual data exploration in SQL
Hitmasu/OpenCNPJ
API pública de busca e consulta de CNPJs do Brasil
J-Tech-Japan/Sekiban
Sekiban - an Opinionated Event Sourcing and CQRS Framework using C#. It can store data into Azure Cosmos DB, AWS Dynamo DB or Postgres
BDFFZI/Alife
一款专为桌宠方向打造的独特AIAgent。功能超全,一键安装,跨平台;全功能插件化,AI自主热修改,异常隔离;动态分层上下文,永久唯一会话,稳定可成长的长期记忆;类游戏引擎交互策略,并行流式执行器,高效实时交互;人工手搓提示词,各种小巧思,大幅降低token开销;具有极高的可玩性和成长上限,非常适合真正想入坑养AI的用户。
ErrorLSC/Polars.NET
.NET DataFrame Engine, powered by Arrow and Polars
RusselWebber/xlDuckDb
Use DuckDB within Excel with the xlDuckDb addin
idaholab/DeepLynx
DeepLynx Nexus is version 2 of the DeepLynx data warehouse, and acts as the central integration point for the DeepLynx data ecosystem. Nexus is a functional data catalog and digital thread tool, allowing users to track metadata from disparate sources and identify ontological and semantic connections between data. It is written in C# and React.
Version Downloads Last Updated
2.0.0-preview.1 54 11/9/2026
1.5.6.1 89,005 10/15/2026
1.5.6 124,739 9/28/2026
1.5.5 504,656 7/26/2026
1.5.3 451,594 5/24/2026
1.5.2 175,934 4/24/2026
1.5.0 204,936 3/10/2026
1.4.4 213,884 2/3/2026
1.4.4-alpha.2 3,661 12/19/2025
1.4.3 124,807 12/11/2025
1.4.1 225,492 10/13/2025
1.3.2 241,228 7/8/2025
1.3.0 229,675 6/3/2025
1.2.1 630,387 3/5/2025
1.2.1-alpha.8 433 2/19/2025
1.2.0 209,794 2/6/2025
1.1.3 446,527 11/7/2024
1.1.2.1 89,362 10/21/2024
1.1.2-alpha.5 235 10/10/2024
Loading failed

- Updated to DuckDB v2.0.0

Breaking changes:
- DuckDB.NET.Data 2.0 needs DuckDB.NET.Bindings 2.0: upgrade both packages together
- HUGEINT and UHUGEINT are read as Int128 and UInt128 by default (GetValue, ExecuteScalar, GetFieldType, the schema tables, DataTable and values nested in lists, maps and structs), instead of BigInteger. sum() of an integer column is a HUGEINT, so (BigInteger)command.ExecuteScalar() after a SUM throws: cast to Int128, or read it with GetFieldValue<BigInteger>. VARINT stays BigInteger. A DataTable with such a column is written by WriteXml but not read back by ReadXml unless Int128 and UInt128 are added to the DataSet type allow-list
- IDuckDBAppenderRow has new members AppendValue(Int128?), AppendValue(UInt128?), AppendValue(DateOnly?) and AppendValue(TimeOnly?): a class that implements the interface must add them. With C# 12 (the default for net8.0 projects) an integer constant passed to AppendValue is ambiguous; give it the type of its column, for example (int?)1
- DuckDBDateOnly and DuckDBTimeOnly convert to DateOnly and TimeOnly only explicitly. dateOnly.Equals(duckDBDateOnly) now returns false and dateOnly.CompareTo(duckDBDateOnly) throws: cast the DuckDB value first. Assignments and comparisons that relied on the implicit conversion need a cast, and assemblies built against 1.x that call it need a rebuild
- A typed scalar function with no nullable parameter returns NULL for a NULL argument without being called, for a column as for a constant. In projects without nullable reference types this includes string and object parameters, which were called with null: declare the parameter string? or mark it [AllowNull] to be called. A function closed over string? in a generic method is treated as not nullable
- A FLOAT, DOUBLE or DECIMAL value with a fractional part, read as an integer type, throws InvalidCastException instead of being rounded: cast in SQL (x::INTEGER) or read it as double or decimal and round
- A list item, map key or value or struct field read as a type it cannot be read as throws InvalidCastException instead of ArgumentException or OverflowException. Reads that the column allowed and these paths refused now give the value: an integer as BigInteger, a HUGEINT, UHUGEINT or VARINT as a smaller integer type when it fits, an ENUM as any integer type
- A STRUCT read into a C# struct gives the values of its fields; under JIT every property was left at its default
- A BLOB read with GetValue, ExecuteScalar, GetProviderSpecificValue or as object is a byte[] instead of a Stream, and GetFieldType and the schema tables report byte[]. GetStream and GetFieldValue<Stream> still return a stream. The stream pointed into the reader's memory, so one returned by ExecuteScalar read freed memory
- A DECIMAL of more than 18 digits that fits a decimal keeps the scale of its column: 1.5 from a DECIMAL(38,4) reads as 1.5000, as it does from a DECIMAL(18,4). Equality and arithmetic are unchanged; ToString and serialization show the trailing zeros
- A string with NUL characters is stored in full by the appender, the mapped appender, the results of scalar and table functions, and parameters; it was cut at the first NUL
- A BigInteger appended to a column other than HUGEINT or UHUGEINT throws InvalidOperationException, as an Int128 does; its 16 bytes overwrote neighbouring values
- A table function parameter read with GetValue<T> as a type other than its own, object, a nullable or an interface of it throws InvalidCastException; the bytes were reinterpreted as T
- An Int128 or UInt128 parameter is sent as a HUGEINT or UHUGEINT value instead of text, with DbType VarNumeric
- A DateTime appended to a TIME column stores its time of day; it stored the microseconds of the whole timestamp, more than a day
- A TimeOnly or DuckDBTimeOnly written to a DATE, TIMETZ or timestamp column, and a DateOnly or DuckDBDateOnly written to a TIME column, by the appender or a table function, throw InvalidOperationException instead of storing the bytes of the other type
- A DATE, TIMESTAMP, TIME, TIMETZ or INTERVAL value read into an object property of a class or struct, or with GetValue<object> in a function, is a DateOnly, DateTime, TimeOnly, DateTimeOffset or TimeSpan, the column's own .NET type, instead of the DuckDB struct. Numbers, HUGEINT, ENUM, STRUCT, LIST and MAP values read into object follow the same rule; they threw or gave an empty object
- A class derived from Dictionary<string, object> is refused as a MAP target, as Dictionary<string, object> already was
- ExecuteNonQuery and RecordsAffected return -1 for statements other than INSERT, UPDATE, DELETE, MERGE and COPY, and the reader counts the rows of these statements (#374)
- DbCommand.CommandType defaults to Text and DbParameter.Direction to Input; both started at 0, which is not a valid value (#372)
- GetOrdinal falls back to a case-insensitive search, and throws IndexOutOfRangeException for a missing column (#375)
- Prepare() requires an open connection (#378)
- Unsupported savepoint operations fail the same way on every method (#380)

New features:
- Int128 and UInt128 (#370): read HUGEINT and UHUGEINT as Int128 and UInt128, and every other integer column, VARINT, a whole DECIMAL and ENUM when the value fits; append them with AppendValue and the mapped appender; use them as scalar and table function types; Int128 and UInt128 parameters are sent as HUGEINT and UHUGEINT values
- DuckDBCommand.Prepare() prepares the statement once and keeps it on the connection, shared by commands with the same text, until the connection closes; later executions only bind and execute. A command of several statements is not prepared. After a schema change that alters a parameter's type, call Prepare() again
- TIME_NS columns can be read and written as TimeOnly, TimeSpan, DateTime and DuckDBTimeOnly, in columns, lists, maps, structs and DuckDBValue (#386, #387)
- Typed reads of LIST, MAP and STRUCT columns: a List<T> of any element type, a Dictionary<TKey, TValue> and a class or struct are filled without boxing, and lists and dictionaries are created at their size. Classes derived from List<T> or Dictionary<TKey, TValue>, generic or not, are read through their base. The common element, key and value types also work under Native AOT, where lists of most element types threw MissingMethodException
- [AllowNull] on a scalar function parameter makes it nullable, as string? and [MaybeNull] do
- GetFieldValue<byte[]> reads a BLOB, also as a list item, map value or struct field (#384)
- GetBytes and GetChars read part of a BLOB or a string into a buffer, and return the length for a null buffer (#377)
- GetSchema("DataTypes") and the ADO.NET metadata collections describe DuckDB's types (#364)
- GetValues copies only as many values as the array holds (#376), and Close() can be called more than once (#373)

Thanks to Alaric Dailey (@alaricd) for his pull requests that brought DuckDB.NET's ADO.NET behaviour in line with the documented contracts, and to Michał Rusinek (@Mr444-dev) for TIME_NS support.