- Table engine configuration via fluent API: MergeTree, ReplacingMergeTree, SummingMergeTree, AggregatingMergeTree, CollapsingMergeTree, VersionedCollapsingMergeTree, GraphiteMergeTree, plus simple engines (Log, TinyLog, StripeLog, Memory).
- Engine clauses: ORDER BY, PARTITION BY, PRIMARY KEY, SAMPLE BY, TTL, SETTINGS — all configurable per-entity.
- Column-level DDL features: CODEC, TTL, COMMENT, DEFAULT values.
- Data-skipping indexes: configurable type, granularity, and parameters.
- Migrations support:
dotnet ef migrations add/database updatewith full DDL generation (CREATE TABLE, ALTER TABLE ADD/DROP/MODIFY/RENAME COLUMN, RENAME TABLE, CREATE/DROP DATABASE). - Model validation: engine parameter columns checked for existence and correct store types (Int8 for sign, UInt8 for isDeleted). Foreign key warnings.
- Default engine convention: MergeTree with ORDER BY derived from primary key when no explicit engine is configured.
- Lambda-based overloads for engine configuration (e.g.
HasReplacingMergeTreeEngine<T>(e => e.Version)). ListToArrayConverterhandles null → empty array for ClickHouseArray(T)columns.- Nullable wrapping correctly skips container types (Array, Map, Tuple, Variant, Dynamic, Json).
- JOINs: INNER JOIN, LEFT JOIN, and CROSS JOIN (via
SelectMany). LEFT JOIN now returns realnullfor non-matching rows — the provider injectsset_join_use_nulls=1automatically on every connection path (UseClickHouse(string),UseClickHouse(DbConnection),UseClickHouse(DbDataSource)). - Correlated subqueries:
Contains/In,Any/EXISTS,All, and scalar subqueries in projections. - Set operations:
Concat(→UNION ALL),Union(→UNION DISTINCT),Intersect,Except, and chained combinations. BareUNIONis rejected by ClickHouse, so the provider always emits explicitALL/DISTINCT. - Inline local collections in queries: LINQ joins and
Containsagainst in-memory collections (int[],List<T>, etc.) now translate through a ClickHouse-compatibleSELECT … UNION ALL …rewrite of EF Core'sValuesExpression. - Expanded collection property support:
IEnumerable<T>,IList<T>,ICollection<T>,IReadOnlyList<T>, andIReadOnlyCollection<T>now round-trip end-to-end as entity properties (via the newEnumerableToArrayConverter<TCollection, T>), joining the already-supportedT[]andList<T>. DisableJoinNullSemantics()option onClickHouseDbContextOptionsBuilder— opts out of the automaticjoin_use_nulls=1injection for environments where the server forbids changing the setting (e.g.readonly=1profiles). LEFT JOIN then returns ClickHouse defaults (0, "") instead of NULL.COUNT(...)results are cast toInt32/Int64in SQL so that set operations involving counts find a common supertype (ClickHouseCOUNTreturnsUInt64).- Scalar subqueries that project
COUNTorSUM(or EF Core'sCOALESCE(COUNT|SUM, 0)wrap) are automatically wrapped withifNull(..., 0)— ClickHouse scalar subqueries return NULL for empty input even for aggregates that standard SQL guarantees non-null. ORDER BYon nullable columns emits explicitNULLS FIRST/NULLS LASTto match .NET/standard-SQL null ordering. Non-nullable columns are left alone soNaNordering on floats isn't disturbed.