Клиент ClickHouse для C#
Официальный клиент C# для подключения к ClickHouse. Исходный код клиента доступен в репозитории GitHub. Изначально разработан Oleg V. Kozlyuk.
Руководство по миграции
- Обновите файл
.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 бит) |
| UseFormDataParameters | bool | false | UseFormDataParameters | Отправлять параметры в виде form data вместо URL-строки запроса |
Управление сессиями
| Свойство | Тип | Значение по умолчанию | Ключ строки подключения | Описание |
|---|---|---|---|---|
| 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
Использование
Подключение
Чтобы подключиться к ClickHouse, создайте ClickHouseConnection со строкой подключения или объект ClickHouseClientSettings. См. раздел Configuration с описанием доступных параметров.
Информация о вашем сервисе ClickHouse Cloud доступна в консоли ClickHouse Cloud.
Выберите сервис и нажмите Connect:

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

Если вы используете самоуправляемый ClickHouse, параметры подключения задаются вашим администратором ClickHouse.
Подключение с помощью строки подключения:
Или, используя ClickHouseClientSettings:
ClickHouseConnectionпредставляет собой "сессию" с сервером. При создании соединения выполняется определение доступных возможностей, запрашивается версия сервера (поэтому при открытии есть небольшие накладные расходы), но в целом многократное создание и уничтожение таких объектов является безопасным.- Рекомендуемое время жизни подключения — один объект подключения на одну большую "транзакцию", охватывающую несколько запросов. Объект
ClickHouseConnectionможет быть долгоживущим. Есть небольшие накладные расходы при запуске подключения, поэтому не рекомендуется создавать объект подключения для каждого запроса. - Если приложение работает с большими объемами транзакций и ему часто требуется создавать/уничтожать объекты
ClickHouseConnection, рекомендуется использоватьIHttpClientFactoryили статический экземплярHttpClientдля управления подключениями.
Создание таблицы
Создайте таблицу с использованием стандартного синтаксиса SQL:
Вставка данных
Вставляйте данные с использованием параметризованных запросов:
Массовая вставка
Используйте ClickHouseBulkCopy для вставки большого количества строк. Он эффективно потоково передаёт данные, используя собственный бинарный построчный формат ClickHouse, работает в параллельном режиме и может разбивать данные на пакеты. Это также позволяет избежать ограничений, связанных с большими наборами параметров, которые вызывают ошибки «URL too long».
Для использования ClickHouseBulkCopy необходимы:
- Целевое подключение (экземпляр
ClickHouseConnection) - Имя целевой таблицы (свойство
DestinationTableName) - Источник данных (
IDataReaderилиIEnumerable<object[]>)
- Для оптимальной производительности ClickHouseBulkCopy использует Task Parallel Library (TPL) для обработки пакетов данных с использованием до 4 параллельных задач вставки (это можно настроить).
- Имена столбцов при необходимости могут быть переданы через свойство
ColumnNames, если в исходных данных столбцов меньше, чем в целевой таблице. - Настраиваемые параметры:
Columns,BatchSize,MaxDegreeOfParallelism. - Перед копированием выполняется запрос
SELECT * FROM <table> LIMIT 0для получения информации о структуре целевой таблицы. Типы передаваемых объектов должны разумно соответствовать типам столбцов целевой таблицы. - Сессии несовместимы с параллельной вставкой. Подключение, передаваемое в
ClickHouseBulkCopy, должно быть без сессий, либо параметрMaxDegreeOfParallelismдолжен быть установлен в значение1.
Выполнение запросов SELECT
Выполняйте запросы SELECT с помощью методов ExecuteReader() или ExecuteReaderAsync(). Возвращаемый DbDataReader предоставляет типизированный доступ к столбцам результата через методы, такие как GetInt64(), GetString() и GetFieldValue<T>().
Вызывайте Read(), чтобы перейти к следующей строке. Метод возвращает false, когда строк больше нет. Обращайтесь к столбцам по индексу (с нуля) или по имени столбца.
Параметры SQL
В ClickHouse стандартный формат параметров в SQL-запросах — {parameter_name:DataType}.
Примеры:
Параметры привязки SQL (bind) передаются как параметры HTTP URI-запроса, поэтому при их чрезмерном количестве может возникнуть исключение «URL too long». Использование ClickHouseBulkInsert позволяет обойти это ограничение.
Идентификатор запроса
Каждый метод, который выполняет запрос, также возвращает query_id в результате. Этот уникальный идентификатор назначается клиентом для каждого запроса и может использоваться для получения данных из таблицы system.query_log (если она включена) или для отмены длительно выполняющихся запросов. При необходимости пользователь может задать идентификатор запроса явно в объекте ClickHouseCommand.
Если вы переопределяете параметр QueryId, необходимо обеспечить его уникальность для каждого вызова. Случайный GUID — хороший вариант.
Необработанный стриминг
Можно передавать данные в определённом формате непосредственно, обходя data reader. Это может быть полезно, если вы хотите сохранить данные в файл в нужном формате. Например:
Вставка из необработанного потока
Используйте InsertRawStreamAsync, чтобы вставлять данные непосредственно из файловых потоков или потоков памяти в форматах, таких как CSV, JSON или любой поддерживаемый формат ClickHouse.
Вставка из CSV‑файла:
См. документацию по настройкам форматов для получения сведений о параметрах, управляющих процессом ингестии данных.
Дополнительные примеры
См. дополнительные практические примеры использования в директории examples репозитория GitHub.
Рекомендации
Время жизни соединения и пул подключений
ClickHouse.Driver внутренне использует System.Net.Http.HttpClient. HttpClient имеет пул подключений для каждой конечной точки (endpoint). В результате:
- Объект
ClickHouseConnectionне имеет отображения 1:1 на TCP‑соединения — несколько сеансов работы с базой данных будут мультиплексироваться поверх нескольких TCP‑соединений на один сервер. - Объекты
ClickHouseConnectionмогут быть «долго живущими»; реальные TCP‑соединения под ними будут переиспользоваться пулом подключений. - Позвольте
HttpClientуправлять пулом подключений внутренне. Не организуйте пул объектовClickHouseConnectionсамостоятельно. - Соединения могут оставаться активными после удаления объекта
ClickHouseConnection. - Это поведение можно настроить, передав пользовательский
HttpClientFactoryилиHttpClientс пользовательскимHttpClientHandler.
Для DI‑окружений предусмотрен специальный конструктор ClickHouseConnection(string connectionString, IHttpClientFactory httpClientFactory, string httpClientName = ""), который заставляет ClickHouseConnection запрашивать именованный HTTP‑клиент.
При использовании пользовательского HttpClient или HttpClientFactory убедитесь, что PooledConnectionIdleTimeout имеет значение меньше, чем keep_alive_timeout сервера, чтобы избежать ошибок из‑за наполовину закрытых соединений. Значение keep_alive_timeout по умолчанию для развертываний в Cloud — 10 секунд.
Обработка DateTime
-
По возможности используйте UTC. Храните метки времени в столбцах
DateTime('UTC')и используйтеDateTimeKind.Utcв коде. Это устраняет неоднозначность, связанную с часовыми поясами. -
Используйте
DateTimeOffsetдля явной обработки часовых поясов. Он всегда представляет конкретный момент времени и включает информацию о смещении. -
Указывайте часовой пояс в подсказках типа параметров HTTP. При использовании параметров с
Unspecifiedзначениями DateTime, записываемыми в столбцы с часовым поясом, отличным от UTC:
Асинхронные вставки
Асинхронные вставки переносят ответственность за формирование батчей с клиента на сервер. Вместо необходимости группировать вставки на стороне клиента сервер буферизует входящие данные и сбрасывает их в хранилище при достижении настраиваемых пороговых значений. Это полезно в сценариях с высокой степенью параллелизма, например в нагрузках обсервабилити, когда множество агентов отправляют небольшие объемы данных.
Включите асинхронные вставки через 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)
Когда сессии включены, запросы сериализуются, чтобы предотвратить одновременное использование одной и той же сессии. Это добавляет накладные расходы для нагрузок, которым не требуется состояние сессии.
Поддерживаемые типы данных
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) | byte[] |
Типы даты и времени
| 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') - Устанавливайте нужный часовой пояс самостоятельно после чтения данных.
Другие типы
| Тип ClickHouse | Тип .NET |
|---|---|
| UUID | Guid |
| IPv4 | IPAddress |
| IPv6 | IPAddress |
| Nothing | DBNull |
| Dynamic | См. примечание |
| Json | JsonObject |
| 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, любой тип, совместимый с Convert.ToString() | |
| FixedString(N) | string, byte[] | String кодируется в UTF-8 и дополняется/усекается; массив byte[] должен содержать ровно 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 | Поведение |
|---|---|
Utc | Момент времени сохраняется без изменений |
Local | Преобразуется в UTC с использованием часового пояса системы; момент сохраняется |
Unspecified | Рассматривается как локальное время в часовом поясе целевого столбца |
Значения DateTimeOffset всегда сохраняют точный момент времени.
Пример: DateTime в UTC (момент сохраняется)
Пример: неопределённый DateTime (локальное «настенное» время)
Рекомендация: для наиболее простого и предсказуемого поведения используйте DateTimeKind.Utc или DateTimeOffset для всех операций с типом DateTime. Это позволит вашему коду работать одинаково независимо от часового пояса сервера, клиента или часового пояса столбца.
HTTP-параметры vs bulk copy
Существует существенное отличие между привязкой HTTP-параметров и bulk copy при записи значений DateTime с Kind Unspecified:
Bulk Copy знает часовой пояс целевого столбца и корректно интерпретирует значения Unspecified в этом часовом поясе.
HTTP-параметры автоматически не знают часовой пояс столбца. Необходимо явно указать его в подсказке типа параметра:
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 |
Другие типы
| Тип ClickHouse | Принимаемые типы .NET | Примечания |
|---|---|---|
| UUID | Guid, string | Строка парсится как Guid |
| IPv4 | IPAddress, string | Должен быть IPv4; строка парсится через IPAddress.Parse() |
| IPv6 | IPAddress, string | Должен быть IPv6; строка парсится через IPAddress.Parse() |
| Nothing | Любой тип | Ничего не записывает (операция no-op) |
| Dynamic | — | Не поддерживается (выбрасывает NotImplementedException) |
| Json | string, JsonObject, любой объект | Строка парсится как JSON; объекты сериализуются через JsonSerializer |
| 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, предоставляя легковесное журналирование, подключаемое по желанию. При его включении драйвер генерирует структурированные сообщения о событиях жизненного цикла подключения, выполнении команд, транспортных операциях и массовой загрузке данных. Журналирование полностью необязательно — приложения, которые не настраивают логгер, продолжают работать без дополнительных накладных расходов.
Быстрый старт
Использование ClickHouseConnection
Использование appsettings.json
Вы можете настроить уровни логирования с помощью стандартной системы конфигурации .NET:
Использование конфигурации в оперативной памяти
Вы также можете настроить детализацию логирования по категориям прямо в коде:
Категории и источники
Драйвер использует отдельные категории, чтобы вы могли точно настраивать уровни логирования для каждого компонента:
| Category | Source | Highlights |
|---|---|---|
ClickHouse.Driver.Connection | ClickHouseConnection | Жизненный цикл соединения, выбор фабрики HTTP‑клиента, открытие/закрытие соединения, управление сессиями. |
ClickHouse.Driver.Command | ClickHouseCommand | Начало и завершение выполнения запроса, замер времени, идентификаторы запросов, статистика сервера и сведения об ошибках. |
ClickHouse.Driver.Transport | ClickHouseConnection | Низкоуровневые потоковые HTTP‑запросы, флаги сжатия, коды статуса ответа и сбои транспортного уровня. |
ClickHouse.Driver.BulkCopy | ClickHouseBulkCopy | Загрузка метаданных, пакетные операции, количество строк и завершение отправки. |
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
Dapper
ClickHouse.Driver можно использовать с Dapper, но анонимные объекты при этом не поддерживаются.
Рабочий пример:
Не поддерживается:
Linq2db
Этот драйвер совместим с linq2db — легковесным ORM и провайдером LINQ для .NET. Подробную документацию см. на сайте проекта.
Пример использования:
Создайте объект DataConnection с использованием провайдера ClickHouse:
Сопоставления таблиц могут задаваться с помощью атрибутов или fluent‑конфигурации. Если имена ваших классов и свойств в точности совпадают с именами таблиц и столбцов, никакая конфигурация не требуется:
Выполнение запросов:
Массовое копирование (Bulk Copy):
Используйте BulkCopyAsync для эффективной массовой вставки данных.
Entity framework core
Entity Framework Core на данный момент не поддерживается.
Ограничения
Столбцы типа AggregateFunction
Столбцы типа AggregateFunction(...) нельзя напрямую использовать в запросах или при вставке данных.
Для вставки:
Чтобы выбрать: