Клиент ClickHouse для C#
Официальный клиент C# для подключения к ClickHouse. Исходный код клиента доступен в репозитории GitHub. Изначально разработан Oleg V. Kozlyuk.
Библиотека предоставляет два основных API:
-
ClickHouseClient(рекомендуется): высокоуровневый, потокобезопасный клиент, предназначенный для использования в виде singleton. Предоставляет простой асинхронный API для выполнения запросов и пакетных вставок. Наиболее подходящий вариант для большинства приложений. -
ADO.NET (
ClickHouseDataSource,ClickHouseConnection,ClickHouseCommand): стандартные абстракции базы данных в .NET. Необходимы для интеграции с ORM (Dapper, Linq2db) и в случаях, когда требуется совместимость с ADO.NET.ClickHouseBulkCopy— вспомогательный класс для эффективной вставки данных с использованием подключения ADO.NET.ClickHouseBulkCopyобъявлен устаревшим и будет удалён в одном из будущих релизов; вместо него используйтеClickHouseClient.InsertBinaryAsync.
Оба API используют общий пул HTTP‑подключений и могут использоваться вместе в одном приложении.
Руководство по миграции
- Обновите файл
.csproj, указав новое имя пакетаClickHouse.Driverи последнюю версию на NuGet. - Замените все вхождения
ClickHouse.ClientнаClickHouse.Driverв вашей кодовой базе.
Поддерживаемые версии .NET
ClickHouse.Driver поддерживает следующие версии .NET:
- .NET Framework 4.6.2
- .NET Framework 4.8
- .NET Standard 2.1
- .NET 6.0
- .NET 8.0
- .NET 9.0
- .NET 10.0
Установка
Установите пакет из NuGet:
Или с помощью менеджера пакетов NuGet:
Быстрый старт
Конфигурация
Существует два способа настройки подключения к ClickHouse:
- Строка подключения: Пары ключ/значение, разделённые точкой с запятой, которые задают хост, учётные данные для аутентификации и другие параметры подключения.
- Объект
ClickHouseClientSettings: Строго типизированный объект конфигурации, который может быть загружен из файлов конфигурации или задан в коде.
Ниже приведён полный список всех параметров, их значений по умолчанию и того, как они влияют на подключение.
Параметры подключения
| Свойство | Тип | Значение по умолчанию | Ключ строки подключения | Описание |
|---|---|---|---|---|
| Host | string | "localhost" | Host | Имя хоста или IP-адрес сервера ClickHouse |
| Port | ushort | 8123 (HTTP) / 8443 (HTTPS) | Port | Номер порта; по умолчанию выбирается в зависимости от протокола |
| Username | string | "default" | Username | Имя пользователя для аутентификации |
| Password | string | "" | Password | Пароль для аутентификации |
| Database | string | "" | Database | База данных по умолчанию; если не задано, используется значение по умолчанию сервера/пользователя |
| Protocol | string | "http" | Protocol | Протокол подключения: "http" или "https" |
| Path | string | null | Path | Путь в URL для сценариев с обратным прокси (например, /clickhouse) |
| Timeout | TimeSpan | 2 минуты | Timeout | Таймаут операции (в строке подключения хранится в секундах) |
Формат данных и сериализация
| Свойство | Тип | По умолчанию | Ключ строки подключения | Описание |
|---|---|---|---|---|
| UseCompression | bool | true | Compression | Включить сжатие gzip при передаче данных |
| UseCustomDecimals | bool | true | UseCustomDecimals | Использовать ClickHouseDecimal для произвольной точности; если false, используется .NET decimal (ограничение 128 бит) |
| ReadStringsAsByteArrays | bool | false | ReadStringsAsByteArrays | Читать столбцы String и FixedString как массивы байтов byte[] вместо строк string; полезно для двоичных данных |
| UseFormDataParameters | bool | false | UseFormDataParameters | Отправлять параметры в виде form data вместо URL-строки запроса |
| JsonReadMode | JsonReadMode | Binary | JsonReadMode | Как возвращаются JSON-данные: Binary (возвращает JsonObject) или String (возвращает исходную строку JSON) |
| JsonWriteMode | JsonWriteMode | String | JsonWriteMode | Как отправляются JSON-данные: String (сериализует через JsonSerializer, принимает любые входные данные) или Binary (только зарегистрированные объекты POCO с подсказками типов) |
Управление сессиями
| Свойство | Тип | Значение по умолчанию | Ключ строки подключения | Описание |
|---|---|---|---|---|
| UseSession | bool | false | UseSession | Включить состояние сессий; выполняет запросы последовательно |
| SessionId | string | null | SessionId | Идентификатор сессии; автоматически генерирует GUID, если null и UseSession имеет значение true |
Флаг UseSession включает сохранение серверной сессии, что позволяет использовать операторы SET и временные таблицы. Сессии будут сброшены после 60 секунд бездействия (тайм-аут по умолчанию). Время жизни сессии можно увеличить, задав параметры сессии с помощью операторов ClickHouse или конфигурации сервера.
Класс ClickHouseConnection обычно поддерживает параллельную работу (несколько потоков могут выполнять запросы одновременно). Однако включение флага UseSession ограничит выполнение одним активным запросом на соединение в любой момент времени (это ограничение на стороне сервера).
Безопасность
| Свойство | Тип | Значение по умолчанию | Ключ строки подключения | Описание |
|---|---|---|---|---|
| SkipServerCertificateValidation | bool | false | — | Отключить проверку HTTPS-сертификата; не использовать в продуктивной среде |
Конфигурация HTTP‑клиента
| Свойство | Тип | Значение по умолчанию | Ключ строки подключения | Описание |
|---|---|---|---|---|
| HttpClient | HttpClient | null | — | Пользовательский предварительно настроенный экземпляр HttpClient |
| HttpClientFactory | IHttpClientFactory | null | — | Пользовательская фабрика для создания экземпляров HttpClient |
| HttpClientName | string | null | — | Имя, используемое HttpClientFactory для создания конкретного клиента |
Логирование и отладка
| Свойство | Тип | Значение по умолчанию | Ключ строки подключения | Описание |
|---|---|---|---|---|
| LoggerFactory | ILoggerFactory | null | — | Фабрика логгеров для диагностического логирования |
| EnableDebugMode | bool | false | — | Включить .NET network tracing (требуется LoggerFactory с уровнем, установленным на Trace); значительное влияние на производительность |
Пользовательские настройки и роли
| Свойство | Тип | Значение по умолчанию | Ключ строки подключения | Описание |
|---|---|---|---|---|
| CustomSettings | IDictionary<string, object> | Пусто | префикс set_* | Настройки сервера ClickHouse, см. примечание ниже. |
| Roles | IReadOnlyList<string> | Пусто | Roles | Роли ClickHouse, перечисленные через запятую (например, Roles=admin,reader) |
При использовании строки подключения для задания пользовательских настроек добавляйте префикс set_, например «set_max_threads=4». При использовании объекта ClickHouseClientSettings префикс set_ добавлять не нужно.
Полный список доступных настроек см. здесь.
Примеры строк подключения
Простое подключение
С пользовательскими настройками ClickHouse
QueryOptions
QueryOptions позволяет переопределять клиентские настройки для отдельных запросов. Все свойства являются необязательными и переопределяют значения по умолчанию клиента только если они заданы.
| Property | Type | Description |
|---|---|---|
| QueryId | string | Пользовательский идентификатор запроса для отслеживания в system.query_log или отмены |
| Database | string | Переопределяет базу данных по умолчанию для этого запроса |
| Roles | IReadOnlyList<string> | Переопределяет роли клиента для этого запроса |
| CustomSettings | IDictionary<string, object> | Настройки сервера ClickHouse для этого запроса (например, max_threads) |
| CustomHeaders | IDictionary<string, string> | Дополнительные HTTP‑заголовки для этого запроса |
| UseSession | bool? | Переопределяет поведение сессии для этого запроса |
| SessionId | string | Идентификатор сессии для этого запроса (требуется UseSession = true) |
| BearerToken | string | Переопределяет токен аутентификации для этого запроса |
| MaxExecutionTime | TimeSpan? | Тайм‑аут выполнения запроса на стороне сервера (передаётся как настройка max_execution_time); сервер отменит запрос при превышении |
Пример:
InsertOptions
InsertOptions расширяет QueryOptions настройками, предназначенными для пакетных операций вставки через InsertBinaryAsync.
| Свойство | Тип | По умолчанию | Описание |
|---|---|---|---|
| BatchSize | int | 100,000 | Количество строк в пакете |
| MaxDegreeOfParallelism | int | 1 | Количество параллельных загрузок пакетов |
| Format | RowBinaryFormat | RowBinary | Бинарный формат: RowBinary или RowBinaryWithDefaults |
Все свойства QueryOptions также доступны в InsertOptions.
Пример:
ClickHouseClient
ClickHouseClient — это рекомендуемый API для взаимодействия с ClickHouse. Он потокобезопасен, предназначен для использования как синглтон и самостоятельно управляет пулом HTTP‑соединений.
Создание клиента
Создайте ClickHouseClient, указав строку подключения, или используйте объект ClickHouseClientSettings. См. раздел Configuration с описанием доступных параметров.
Информация о вашем сервисе ClickHouse Cloud доступна в консоли ClickHouse Cloud.
Выберите сервис и нажмите Connect:

Выберите C#. Ниже будут отображены параметры подключения.

Если вы используете самоуправляемый ClickHouse, параметры подключения задаются вашим администратором ClickHouse.
Подключение с помощью строки подключения:
Или, используя ClickHouseClientSettings:
В сценариях внедрения зависимостей используйте IHttpClientFactory:
ClickHouseClient спроектирован как долгоживущий объект, который используется совместно во всём приложении. Создайте его один раз (обычно как singleton) и переиспользуйте для всех операций с базой данных. Клиент самостоятельно управляет пулом HTTP‑подключений.
Выполнение запросов
Используйте ExecuteNonQueryAsync для команд, не возвращающих результат:
Используйте ExecuteScalarAsync, чтобы получить одно значение:
Вставка данных
Параметризованные вставки
Вставляйте данные, используя параметризованные запросы и метод ExecuteNonQueryAsync. Типы параметров должны быть указаны в SQL с использованием синтаксиса {name:Type}:
Массовые вставки
Используйте InsertBinaryAsync для эффективной вставки большого количества строк. Он выполняет потоковую передачу данных в нативном двоичном формате строк ClickHouse, поддерживает параллельную пакетную загрузку и предотвращает ошибки «URL слишком длинный», которые могут возникать при использовании параметризованных запросов.
Для больших наборов данных настройте пакетную вставку и параллелизм с помощью InsertOptions:
- Клиент автоматически получает структуру таблицы с помощью
SELECT * FROM <table> WHERE 1=0перед вставкой. Передаваемые значения должны соответствовать типам целевых столбцов. - При
MaxDegreeOfParallelism > 1пакеты данных загружаются параллельно. Сеансы несовместимы с параллельной вставкой; либо отключите сеансы, либо установитеMaxDegreeOfParallelism = 1. - Используйте
RowBinaryFormat.RowBinaryWithDefaultsвInsertOptions.Format, если вы хотите, чтобы сервер применял значения DEFAULT для столбцов, которые не были переданы.
Чтение данных
Используйте ExecuteReaderAsync для выполнения запросов SELECT. Возвращаемый ClickHouseDataReader предоставляет типизированный доступ к столбцам результата через методы, такие как GetInt64(), GetString() и GetFieldValue<T>().
Вызывайте Read(), чтобы перейти к следующей строке. Метод возвращает false, когда строк больше нет. Обращайтесь к столбцам по индексу (с нуля) или по имени столбца.
Параметры SQL
В ClickHouse стандартный формат параметров в SQL-запросах — {parameter_name:DataType}.
Примеры:
Параметры привязки SQL (bind) передаются как параметры HTTP URI-запроса, поэтому при их чрезмерном количестве может возникнуть исключение «URL too long». Используйте InsertBinaryAsync для пакетной вставки данных, чтобы избежать этого ограничения.
Идентификатор запроса (Query ID)
Каждому запросу назначается уникальный query_id, который можно использовать для получения данных из таблицы system.query_log или прерывания длительно выполняющихся запросов. Вы можете указать собственный идентификатор запроса с помощью QueryOptions:
Если вы указываете собственный QueryId, убедитесь, что он уникален для каждого запроса. Случайный GUID — хороший выбор.
Необработанный стриминг
Используйте ExecuteRawResultAsync, чтобы передавать результаты запроса в определённом формате непосредственно, обходя data reader. Это полезно для экспорта данных в файлы или их передачи в другие системы:
Распространённые форматы: JSONEachRow, CSV, TSV, Parquet, Native. Полный список вариантов см. в документации по форматам.
Вставка из необработанного потока
Используйте InsertRawStreamAsync, чтобы вставлять данные непосредственно из файловых потоков или потоков памяти в форматах, таких как CSV, JSON, Parquet или любой поддерживаемый формат ClickHouse.
Вставка из CSV‑файла:
См. документацию по настройкам форматов для получения сведений о параметрах, управляющих процессом ингестии данных.
Дополнительные примеры
См. дополнительные практические примеры использования в директории examples репозитория GitHub.
ADO.NET
Библиотека предоставляет полную поддержку ADO.NET через ClickHouseConnection, ClickHouseCommand и ClickHouseDataReader. Этот API необходим для интеграции с ORM (Dapper, Linq2db), а также когда вам нужны стандартные абстракции работы с базами данных в .NET.
Управление временем жизни с ClickHouseDataSource
Всегда создавайте подключения из ClickHouseDataSource, чтобы обеспечить корректное управление временем жизни и работу пула соединений. Этот источник данных внутренне управляет одним экземпляром ClickHouseClient, и все подключения используют его пул HTTP-соединений.
Для внедрения зависимостей:
Не создавайте ClickHouseConnection напрямую в продакшн-коде. Каждое такое создание инициализирует новый HTTP‑клиент и пул соединений, что под нагрузкой может привести к исчерпанию сокетов:
Вместо этого всегда используйте ClickHouseDataSource или один общий экземпляр ClickHouseClient.
Использование ClickHouseCommand
Создавайте команды из подключения для выполнения SQL-запросов:
Методы выполнения команд:
ExecuteNonQueryAsync()- для INSERT, UPDATE, DELETE и DDL-командExecuteScalarAsync()- возвращает первый столбец первой строкиExecuteReaderAsync()- возвращаетClickHouseDataReaderдля перебора результатов
Использование ClickHouseDataReader
ClickHouseDataReader предоставляет доступ к результатам запроса с сохранением типов:
Рекомендации
Время жизни соединения и пул подключений
ClickHouse.Driver внутренне использует System.Net.Http.HttpClient. HttpClient имеет пул подключений для каждой конечной точки (endpoint). В результате:
- Сеансы работы с базой данных мультиплексируются через HTTP‑соединения, которыми управляет пул подключений.
- HTTP‑соединения автоматически переиспользуются пулом.
- Соединения могут оставаться активными после удаления объектов
ClickHouseClientилиClickHouseConnection.
Рекомендуемые шаблоны использования:
| Сценарий | Рекомендуемый подход |
|---|---|
| Общий случай | Использовать синглтон ClickHouseClient |
| ADO.NET / ORM | Использовать ClickHouseDataSource (создаёт соединения, которые разделяют один и тот же пул) |
| DI‑окружения | Регистрировать ClickHouseClient или ClickHouseDataSource как синглтон с IHttpClientFactory |
При использовании пользовательского HttpClient или HttpClientFactory убедитесь, что PooledConnectionIdleTimeout имеет значение меньше, чем keep_alive_timeout сервера, чтобы избежать ошибок из‑за наполовину закрытых соединений. Значение keep_alive_timeout по умолчанию для развертываний в Cloud — 10 секунд.
Избегайте создания множества экземпляров ClickHouseClient или отдельных ClickHouseConnection без общего HttpClient. Каждый экземпляр создаёт собственный пул подключений.
Обработка DateTime
-
По возможности используйте UTC. Храните метки времени в столбцах
DateTime('UTC')и используйтеDateTimeKind.Utcв коде. Это устраняет неоднозначность, связанную с часовыми поясами. -
Используйте
DateTimeOffsetдля явной обработки часовых поясов. Он всегда представляет конкретный момент времени и включает информацию о смещении. -
Указывайте часовой пояс в подсказках типов SQL. При использовании параметров с
Unspecifiedзначениями DateTime, записываемыми в столбцы с часовым поясом, отличным от UTC, включайте часовой пояс в SQL:
Асинхронные вставки
Асинхронные вставки переносят ответственность за формирование батчей с клиента на сервер. Вместо необходимости группировать вставки на стороне клиента сервер буферизует входящие данные и сбрасывает их в хранилище при достижении настраиваемых пороговых значений. Это полезно в сценариях с высокой степенью параллелизма, например в нагрузках обсервабилити, когда множество агентов отправляют небольшие объемы данных.
Включите асинхронные вставки через CustomSettings или строку подключения:
Два режима (управляются параметром wait_for_async_insert):
| Mode | Behavior | Use case |
|---|---|---|
wait_for_async_insert=1 | Вставка (INSERT) завершается после сброса данных на диск. Ошибки возвращаются клиенту. | Рекомендуется для большинства нагрузок |
wait_for_async_insert=0 | Вставка (INSERT) завершается сразу после буферизации данных. Нет гарантии сохранения данных. | Только когда допустима потеря данных |
При wait_for_async_insert=0 ошибки возникают только во время flush и не могут быть однозначно сопоставлены с исходной вставкой. Клиент также не создает обратного давления, что повышает риск перегрузки сервера.
Ключевые настройки:
| Setting | Description |
|---|---|
async_insert_max_data_size | Выполнить flush, когда буфер достигает указанного размера (в байтах) |
async_insert_busy_timeout_ms | Выполнить flush по истечении указанного тайм-аута (в миллисекундах) |
async_insert_max_query_number | Выполнить flush после накопления указанного числа запросов |
Сессии
Включайте сессии только тогда, когда вам нужны серверные возможности с сохранением состояния, например:
- Временные таблицы (
CREATE TEMPORARY TABLE) - Сохранение контекста запроса между несколькими командами
- Настройки на уровне сессии (
SET max_threads = 4)
Когда сессии включены, запросы сериализуются, чтобы предотвратить одновременное использование одной и той же сессии. Это добавляет накладные расходы для нагрузок, которым не требуется состояние сессии.
Использование ADO.NET (для совместимости с ORM):
Поддерживаемые типы данных
ClickHouse.Driver поддерживает все типы данных ClickHouse. В приведённых ниже таблицах показаны сопоставления между типами ClickHouse и нативными типами .NET при чтении данных из базы данных.
Сопоставление типов: чтение из ClickHouse
Целочисленные типы
| Тип в ClickHouse | Тип в .NET |
|---|---|
| Int8 | sbyte |
| UInt8 | byte |
| Int16 | short |
| UInt16 | ushort |
| Int32 | int |
| UInt32 | uint |
| Int64 | long |
| UInt64 | ulong |
| Int128 | BigInteger |
| UInt128 | BigInteger |
| Int256 | BigInteger |
| UInt256 | BigInteger |
Типы с плавающей запятой
| Тип ClickHouse | Тип .NET |
|---|---|
| Float32 | float |
| Float64 | double |
| BFloat16 | float |
Типы Decimal
| Тип ClickHouse | Тип .NET |
|---|---|
| Decimal(P, S) | decimal / ClickHouseDecimal |
| Decimal32(S) | decimal / ClickHouseDecimal |
| Decimal64(S) | decimal / ClickHouseDecimal |
| Decimal128(S) | decimal / ClickHouseDecimal |
| Decimal256(S) | decimal / ClickHouseDecimal |
Преобразование типов Decimal управляется настройкой UseCustomDecimals.
Булев тип
| Тип ClickHouse | Тип .NET |
|---|---|
| Bool | bool |
Строковые типы
| Тип ClickHouse | Тип .NET |
|---|---|
| String | string |
| FixedString(N) | string |
По умолчанию столбцы String и FixedString(N) возвращаются как string. Установите параметр ReadStringsAsByteArrays=true в строке подключения, чтобы считывать их как byte[]. Это полезно при хранении двоичных данных, которые могут не быть корректной последовательностью в кодировке UTF-8.
Типы даты и времени
| ClickHouse Type | .NET Type |
|---|---|
| Date | DateTime |
| Date32 | DateTime |
| DateTime | DateTime |
| DateTime32 | DateTime |
| DateTime64 | DateTime |
| Time | TimeSpan |
| Time64 | TimeSpan |
ClickHouse хранит значения DateTime и DateTime64 во внутреннем представлении как Unix-временные метки (Unix timestamps — секунды или доли секунды, прошедшие с начала эпохи Unix). Хотя хранение всегда ведётся в UTC, у столбцов может быть привязан часовой пояс, который влияет на то, как значения отображаются и интерпретируются.
При чтении значений DateTime свойство DateTime.Kind устанавливается на основе часового пояса столбца:
| Column Definition | Returned DateTime.Kind | Notes |
|---|---|---|
DateTime('UTC') | Utc | Явный часовой пояс UTC |
DateTime('Europe/Amsterdam') | Unspecified | Применяется часовой пояс со смещением |
DateTime | Unspecified | Локальное (wall-clock) время сохраняется как есть |
Для столбцов с часовым поясом, отличным от UTC, возвращаемое значение DateTime представляет локальное (wall-clock) время в соответствующем часовом поясе. Используйте ClickHouseDataReader.GetDateTimeOffset() для получения DateTimeOffset с корректным смещением для этого часового пояса:
Для столбцов без явного часового пояса (т.е. DateTime вместо DateTime('Europe/Amsterdam')) драйвер возвращает DateTime с Kind=Unspecified. Это позволяет сохранить «настенное» время в точности в том виде, как оно хранится, не делая предположений о часовом поясе.
Если вам требуется поведение с учетом часового пояса для столбцов без явного часового пояса, то:
- Используйте явные часовые пояса в определениях столбцов:
DateTime('UTC')илиDateTime('Europe/Amsterdam') - Устанавливайте нужный часовой пояс самостоятельно после чтения данных.
Тип JSON
| ClickHouse Type | .NET Type | Notes |
|---|---|---|
| Json | JsonObject | По умолчанию (JsonReadMode=Binary) |
| Json | string | При JsonReadMode=String |
Тип возвращаемого значения JSON-столбцов определяется параметром JsonReadMode:
-
Binary(по умолчанию): ВозвращаетSystem.Text.Json.Nodes.JsonObject. Обеспечивает структурированный доступ к данным JSON, но специализированные типы ClickHouse (такие как IP-адреса, UUID, большие десятичные числа) преобразуются в их строковые представления внутри JSON-структуры. -
String: Возвращает «сырое» значение JSON какstring. Сохраняет точное представление JSON из ClickHouse, что полезно, когда нужно передать JSON дальше без парсинга или когда вы хотите выполнять десериализацию самостоятельно.
Другие типы
| Тип ClickHouse | Тип .NET |
|---|---|
| UUID | Guid |
| IPv4 | IPAddress |
| IPv6 | IPAddress |
| Nothing | DBNull |
| Dynamic | См. примечание |
| Array(T) | T[] |
| Tuple(T1, T2, ...) | Tuple<T1, T2, ...> / LargeTuple |
| Map(K, V) | Dictionary<K, V> |
| Nullable(T) | T? |
| Enum8 | string |
| Enum16 | string |
| LowCardinality(T) | Такой же, как T |
| SimpleAggregateFunction | Такой же, как базовый тип |
| Nested(...) | Tuple[] |
| Variant(T1, T2, ...) | См. примечание |
| QBit(T, dimension) | T[] |
Типы Dynamic и Variant будут преобразованы в тип, соответствующий фактическому базовому типу в каждой строке.
Типы геометрии
| Тип ClickHouse | Тип .NET |
|---|---|
| Point | Tuple<double, double> |
| Ring | Tuple<double, double>[] |
| LineString | Tuple<double, double>[] |
| Polygon | Ring[] |
| MultiLineString | LineString[] |
| MultiPolygon | Polygon[] |
| Geometry | См. примечание |
Тип Geometry — это тип Variant, который может содержать любой из геометрических типов. Он будет преобразован в соответствующий тип.
Сопоставление типов: запись в ClickHouse
При вставке данных драйвер преобразует типы .NET в соответствующие типы ClickHouse. В таблицах ниже показано, какие типы .NET поддерживаются для каждого типа столбца ClickHouse.
Целочисленные типы
| Тип ClickHouse | Принимаемые типы .NET | Примечания |
|---|---|---|
| Int8 | sbyte, любой, совместимый с Convert.ToSByte() | |
| UInt8 | byte, любой, совместимый с Convert.ToByte() | |
| Int16 | short, любой, совместимый с Convert.ToInt16() | |
| UInt16 | ushort, любой, совместимый с Convert.ToUInt16() | |
| Int32 | int, любой, совместимый с Convert.ToInt32() | |
| UInt32 | uint, любой, совместимый с Convert.ToUInt32() | |
| Int64 | long, любой, совместимый с Convert.ToInt64() | |
| UInt64 | ulong, любой, совместимый с Convert.ToUInt64() | |
| Int128 | BigInteger, decimal, double, float, int, uint, long, ulong, любой, совместимый с Convert.ToInt64() | |
| UInt128 | BigInteger, decimal, double, float, int, uint, long, ulong, любой, совместимый с Convert.ToInt64() | |
| Int256 | BigInteger, decimal, double, float, int, uint, long, ulong, любой, совместимый с Convert.ToInt64() | |
| UInt256 | BigInteger, decimal, double, float, int, uint, long, ulong, любой, совместимый с Convert.ToInt64() |
Типы с плавающей запятой
| Тип ClickHouse | Поддерживаемые типы .NET | Примечания |
|---|---|---|
| Float32 | float, любой тип, совместимый с Convert.ToSingle() | |
| Float64 | double, любой тип, совместимый с Convert.ToDouble() | |
| BFloat16 | float, любой тип, совместимый с Convert.ToSingle() | Усекает значение до 16-битного формата brain float |
Логический тип
| Тип ClickHouse | Допустимые типы .NET | Примечания |
|---|---|---|
| Bool | bool |
Строковые типы
| Тип ClickHouse | Допустимые типы .NET | Примечания |
|---|---|---|
| String | string, byte[], ReadOnlyMemory<byte>, Stream | Двоичные типы записываются напрямую; потоки могут как поддерживать произвольное позиционирование (seek), так и не поддерживать его |
| FixedString(N) | string, byte[], ReadOnlyMemory<byte>, Stream | String кодируется в UTF-8 и дополняется; двоичные типы должны содержать ровно N байт |
Типы даты и времени
| Тип ClickHouse | Допустимые типы .NET | Примечания |
|---|---|---|
| Date | DateTime, DateTimeOffset, DateOnly, типы NodaTime | Преобразуется в количество Unix-дней как UInt16 |
| Date32 | DateTime, DateTimeOffset, DateOnly, типы NodaTime | Преобразуется в количество Unix-дней как Int32 |
| DateTime | DateTime, DateTimeOffset, DateOnly, типы NodaTime | См. подробности ниже |
| DateTime32 | DateTime, DateTimeOffset, DateOnly, типы NodaTime | То же, что и DateTime |
| DateTime64 | DateTime, DateTimeOffset, DateOnly, типы NodaTime | Точность зависит от параметра Scale |
| Time | TimeSpan, int | Ограничивается диапазоном ±999:59:59; значения int интерпретируются как секунды |
| Time64 | TimeSpan, decimal, double, float, int, long, string | Строка разбирается как [-]HHH:MM:SS[.fraction]; ограничивается до ±999:59:59.999999999 |
Драйвер учитывает DateTime.Kind при записи значений:
| DateTime.Kind | HTTP-параметры | Пакетная загрузка |
|---|---|---|
| Utc | Момент времени сохраняется | Момент времени сохраняется |
| Local | Момент времени сохраняется | Момент времени сохраняется |
| Unspecified | Рассматривается как локальное «настенное» время в часовом поясе типа параметра (по умолчанию UTC) | Рассматривается как локальное «настенное» время в часовом поясе столбца |
Значения DateTimeOffset всегда сохраняют точный момент времени.
Пример: DateTime в UTC (момент сохраняется)
Пример: неопределённый DateTime (локальное «настенное» время)
Рекомендация: для наиболее простого и предсказуемого поведения используйте DateTimeKind.Utc или DateTimeOffset для всех операций с типом DateTime. Это позволит вашему коду работать одинаково независимо от часового пояса сервера, клиента или часового пояса столбца.
HTTP-параметры vs bulk copy
Существует существенное отличие между привязкой HTTP-параметров и bulk copy при записи значений DateTime с Kind Unspecified:
Bulk Copy знает часовой пояс целевого столбца и корректно интерпретирует значения Unspecified в этом часовом поясе.
HTTP-параметры автоматически не знают часовой пояс столбца. Необходимо явно указать его в подсказке SQL-типа:
DateTime.Kind | Целевой столбец | HTTP-параметр (с указанием часового пояса) | HTTP-параметр (без указания часового пояса) | Массовое копирование |
|---|---|---|---|---|
Utc | UTC | Момент сохраняется | Момент сохраняется | Момент сохраняется |
Utc | Europe/Amsterdam | Момент сохраняется | Момент сохраняется | Момент сохраняется |
Local | Любой | Момент сохраняется | Момент сохраняется | Момент сохраняется |
Unspecified | UTC | Интерпретируется как UTC | Интерпретируется как UTC | Интерпретируется как UTC |
Unspecified | Europe/Amsterdam | Интерпретируется как время Амстердама | Интерпретируется как UTC | Интерпретируется как временем Амстердама |
Типы Decimal
| Тип ClickHouse | Поддерживаемые типы .NET | Примечания |
|---|---|---|
| Decimal(P,S) | decimal, ClickHouseDecimal, любой тип, совместимый с Convert.ToDecimal() | Выбрасывает исключение OverflowException, если превышена точность |
| Decimal32 | decimal, ClickHouseDecimal, любой тип, совместимый с Convert.ToDecimal() | Максимальная точность 9 |
| Decimal64 | decimal, ClickHouseDecimal, любой тип, совместимый с Convert.ToDecimal() | Максимальная точность 18 |
| Decimal128 | decimal, ClickHouseDecimal, любой тип, совместимый с Convert.ToDecimal() | Максимальная точность 38 |
| Decimal256 | decimal, ClickHouseDecimal, любой тип, совместимый с Convert.ToDecimal() | Максимальная точность 76 |
Тип JSON
| Тип ClickHouse | Допустимые типы .NET | Примечания |
|---|---|---|
| Json | string, JsonObject, JsonNode, любой объект | Поведение зависит от настройки JsonWriteMode |
Поведение при записи JSON управляется настройкой JsonWriteMode:
| Тип входных данных | JsonWriteMode.String (по умолчанию) | JsonWriteMode.Binary |
|---|---|---|
string | Передаётся напрямую | Выбрасывает ArgumentException |
JsonObject | Сериализуется через ToJsonString() | Выбрасывает ArgumentException |
JsonNode | Сериализуется через ToJsonString() | Выбрасывает ArgumentException |
| Зарегистрированный POCO | Сериализуется через JsonSerializer.Serialize() | Бинарное кодирование с подсказками типов, поддерживаются пользовательские атрибуты пути |
| Незарегистрированный POCO / анонимный объект | Сериализуется через JsonSerializer.Serialize() | Выбрасывает ClickHouseJsonSerializationException |
-
String(по умолчанию): Принимаетstring,JsonObject,JsonNodeили любой объект. Все входные данные сериализуются с помощьюSystem.Text.Json.JsonSerializerи отправляются как JSON-строки для разбора на стороне сервера. Это наиболее гибкий режим, который работает без регистрации типов. -
Binary: Принимает только зарегистрированные типы POCO. Данные конвертируются в бинарный JSON-формат ClickHouse на стороне клиента с полной поддержкой подсказок типов. Перед использованием требуется вызватьconnection.RegisterJsonSerializationType<T>(). Запись значенийstringилиJsonNodeв этом режиме приводит к выбросуArgumentException.
Типизированные JSON-столбцы
Когда у JSON-столбца есть подсказки по типам (например, JSON(id UInt64, price Decimal128(2))), драйвер использует их, чтобы сериализовывать значения с полным сохранением информации о типах. Это сохраняет точность для таких типов, как UInt64, Decimal, UUID и DateTime64, которые в противном случае теряли бы её при сериализации в виде обычного JSON.
Сериализация POCO
Объекты POCO можно записывать в JSON-столбцы двумя способами в зависимости от значения JsonWriteMode:
Строковый режим (по умолчанию): объекты POCO сериализуются через System.Text.Json.JsonSerializer. Регистрация типов не требуется. Это самый простой подход, который работает и с анонимными объектами.
Бинарный режим: объекты POCO сериализуются с использованием бинарного JSON-формата драйвера с полной поддержкой подсказок типов (type hints). Типы должны быть зарегистрированы с помощью connection.RegisterJsonSerializationType<T>() перед использованием. В этом режиме поддерживаются пользовательские отображения путей через атрибуты:
-
[ClickHouseJsonPath("path")]: Отображает свойство на пользовательский JSON-путь. Полезно для вложенных структур или когда имя свойства отличается от требуемого JSON-ключа. Работает только в бинарном режиме. -
[ClickHouseJsonIgnore]: Исключает свойство из сериализации. Работает только в бинарном режиме.
Сопоставление имени свойства с подсказками типа столбца выполняется с учётом регистра. Свойство UserId будет сопоставлено только с подсказкой, определённой как UserId, а не userid. Это соответствует поведению ClickHouse, который позволяет путям вроде userName и UserName существовать как отдельные поля.
Ограничения (только бинарный режим):
- Типы POCO должны быть зарегистрированы на подключении с помощью
connection.RegisterJsonSerializationType<T>()до сериализации. Попытка сериализовать незарегистрированный тип приводит к возникновениюClickHouseJsonSerializationException. - Свойства-словари и массивы/списки требуют подсказок типов в определении столбца для корректной сериализации. Без подсказок используйте вместо этого строковый режим (String mode).
- Значения
nullв свойствах POCO записываются только тогда, когда путь имеет подсказку типаNullable(T)в определении столбца. ClickHouse не допускает типыNullableвнутри динамических JSON-путей, поэтому свойства сnullбез подсказок пропускаются. - Атрибуты
ClickHouseJsonPathиClickHouseJsonIgnoreигнорируются в строковом режиме (они работают только в бинарном режиме).
Другие типы
| Тип ClickHouse | Принимаемые типы .NET | Примечания |
|---|---|---|
| UUID | Guid, string | Строка парсится как Guid |
| IPv4 | IPAddress, string | Должен быть IPv4; строка парсится через IPAddress.Parse() |
| IPv6 | IPAddress, string | Должен быть IPv6; строка парсится через IPAddress.Parse() |
| Nothing | Любой тип | Ничего не записывает (операция no-op) |
| Dynamic | — | Не поддерживается (выбрасывает NotImplementedException) |
| Array(T) | IList, null | При значении null записывается пустой массив |
| Tuple(T1, T2, ...) | ITuple, IList | Количество элементов должно соответствовать арности кортежа |
| Map(K, V) | IDictionary | |
| Nullable(T) | null, DBNull или типы, принимаемые T | Перед значением записывается байт флага null |
| Enum8 | string, sbyte, числовые типы | Строковое значение ищется в словаре enum |
| Enum16 | string, short, числовые типы | Строковое значение ищется в словаре enum |
| LowCardinality(T) | Типы, принимаемые T | Делегирует базовому типу |
| SimpleAggregateFunction | Типы, принимаемые базовым типом | Делегирует базовому типу |
| Nested(...) | IList кортежей | Количество элементов должно соответствовать количеству полей |
| Variant(T1, T2, ...) | Значение, соответствующее одному из T1, T2, ... | Выбрасывает ArgumentException, если нет совпадения типа |
| QBit(T, dim) | IList | Делегирует типу Array; размерность — только метаданные |
Геометрические типы
| Тип ClickHouse | Допустимые типы .NET | Примечания |
|---|---|---|
| Point | System.Drawing.Point, ITuple, IList (2 элемента) | |
| Ring | IList из Point | |
| LineString | IList из Point | |
| Polygon | IList из Ring | |
| MultiLineString | IList из LineString | |
| MultiPolygon | IList из Polygon | |
| Geometry | Любой из указанных выше геометрических типов | Обобщающий вариант всех геометрических типов |
Запись не поддерживается
| Тип ClickHouse | Примечания |
|---|---|
| Dynamic | Вызывает исключение NotImplementedException |
| AggregateFunction | Вызывает исключение AggregateFunctionException |
Обработка вложенных типов
Вложенные типы ClickHouse (Nested(...)) можно читать и записывать с использованием семантики массивов.
Журналирование и диагностика
Клиент ClickHouse для .NET интегрируется с абстракциями логирования Microsoft.Extensions.Logging, предоставляя легковесное журналирование, подключаемое по желанию. При его включении драйвер генерирует структурированные сообщения о событиях жизненного цикла подключения, выполнении команд, транспортных операциях и массовых операциях вставки. Журналирование полностью необязательно — приложения, которые не настраивают логгер, продолжают работать без дополнительных накладных расходов.
Быстрый старт
Использование appsettings.json
Вы можете настроить уровни логирования с помощью стандартной системы конфигурации .NET:
Использование конфигурации в оперативной памяти
Вы также можете настроить детализацию логирования по категориям прямо в коде:
Категории и источники
Драйвер использует отдельные категории, чтобы вы могли точно настраивать уровни логирования для каждого компонента:
| Category | Source | Highlights |
|---|---|---|
ClickHouse.Driver.Connection | ClickHouseConnection | Жизненный цикл соединения, выбор фабрики HTTP‑клиента, открытие/закрытие соединения, управление сессиями. |
ClickHouse.Driver.Command | ClickHouseCommand | Начало и завершение выполнения запроса, замер времени, идентификаторы запросов, статистика сервера и сведения об ошибках. |
ClickHouse.Driver.Transport | ClickHouseConnection | Низкоуровневые потоковые HTTP‑запросы, флаги сжатия, коды статуса ответа и сбои транспортного уровня. |
ClickHouse.Driver.Client | ClickHouseClient | Бинарная вставка, запросы и другие операции. |
ClickHouse.Driver.NetTrace | TraceHelper | Отслеживание сетевых операций, только при включённом режиме отладки. |
Пример: диагностика неполадок подключения
В журнал будет записано:
- выбор фабрики HTTP-клиента (пул по умолчанию по сравнению с одиночным подключением)
- конфигурация HTTP-обработчика (SocketsHttpHandler или HttpClientHandler)
- настройки пула подключений (MaxConnectionsPerServer, PooledConnectionLifetime и т. д.)
- параметры тайм-аутов (ConnectTimeout, Expect100ContinueTimeout и т. д.)
- конфигурация SSL/TLS
- события открытия и закрытия подключений
- отслеживание идентификаторов сессий
Режим отладки: трассировка сети и диагностика
Чтобы упростить диагностику сетевых проблем, библиотека драйвера предоставляет вспомогательный инструмент, позволяющий включить низкоуровневую трассировку внутренних сетевых механизмов .NET. Чтобы включить её, необходимо передать LoggerFactory с уровнем Trace и установить EnableDebugMode в значение true (или включить её вручную через класс ClickHouse.Driver.Diagnostic.TraceHelper). События будут логироваться в категорию ClickHouse.Driver.NetTrace. Предупреждение: это приведёт к генерации чрезвычайно подробных логов и повлияет на производительность. Не рекомендуется включать режим отладки в продуктивной среде.
OpenTelemetry
Драйвер предоставляет встроенную поддержку распределённого трейсинга OpenTelemetry через API .NET System.Diagnostics.Activity. При его включении драйвер генерирует спаны для операций с базой данных, которые могут быть экспортированы в обсервабилити-бэкенды, такие как Jaeger или сам ClickHouse (через OpenTelemetry Collector).
Включение трассировки
В приложениях ASP.NET Core добавьте ActivitySource драйвера ClickHouse в конфигурацию OpenTelemetry:
Для консольных приложений, тестирования или ручной настройки:
Атрибуты спана
Каждый спан включает стандартные атрибуты базы данных OpenTelemetry, а также специфичные для ClickHouse статистические данные по запросу, которые можно использовать для отладки.
| Атрибут | Описание |
|---|---|
db.system | Всегда "clickhouse" |
db.name | Имя базы данных |
db.user | Имя пользователя |
db.statement | SQL-запрос (если включено) |
db.clickhouse.read_rows | Количество строк, прочитанных запросом |
db.clickhouse.read_bytes | Количество байт, прочитанных запросом |
db.clickhouse.written_rows | Количество строк, записанных запросом |
db.clickhouse.written_bytes | Количество байт, записанных запросом |
db.clickhouse.elapsed_ns | Время выполнения на стороне сервера в наносекундах |
Параметры конфигурации
Настройте поведение трассировки с помощью ClickHouseDiagnosticsOptions:
Включение IncludeSqlInActivityTags может привести к раскрытию конфиденциальных данных в ваших трассировках. Используйте с осторожностью в производственных средах.
Конфигурация TLS
При подключении к ClickHouse по HTTPS вы можете по‑разному настроить работу TLS/SSL.
Пользовательская проверка сертификатов
Для продакшн-сред, где требуется собственная логика проверки сертификатов, используйте свой HttpClient с настроенным обработчиком ServerCertificateCustomValidationCallback:
Важные замечания при передаче собственного HttpClient
- Автоматическая декомпрессия: необходимо включить
AutomaticDecompression, если сжатие не отключено (по умолчанию сжатие включено). - Тайм-аут простоя: установите
PooledConnectionIdleTimeoutменьше, чемkeep_alive_timeoutсервера (10 секунд для ClickHouse Cloud), чтобы избежать ошибок подключения из‑за полуоткрытых соединений.
Поддержка ORM
ORM-фреймворки используют API ADO.NET (ClickHouseConnection). Для корректного управления жизненным циклом подключений создавайте их из ClickHouseDataSource:
Dapper
ClickHouse.Driver можно использовать с Dapper, но анонимные объекты при этом не поддерживаются.
Рабочий пример:
Не поддерживается:
Linq2db
Этот драйвер совместим с linq2db — легковесным ORM и провайдером LINQ для .NET. Подробную документацию см. на сайте проекта.
Пример использования:
Создайте объект DataConnection с использованием провайдера ClickHouse:
Сопоставления таблиц могут задаваться с помощью атрибутов или fluent‑конфигурации. Если имена ваших классов и свойств в точности совпадают с именами таблиц и столбцов, никакая конфигурация не требуется:
Выполнение запросов:
Массовое копирование (Bulk Copy):
Используйте BulkCopyAsync для эффективной массовой вставки данных.
Entity framework core
Entity Framework Core на данный момент не поддерживается.
Ограничения
Столбцы типа AggregateFunction
Столбцы типа AggregateFunction(...) нельзя напрямую использовать в запросах или при вставке данных.
Для вставки:
Чтобы выбрать: