EntityFrameworkCore.Doris
0.1.0-beta.1
dotnet add package EntityFrameworkCore.Doris --version 0.1.0-beta.1
NuGet\Install-Package EntityFrameworkCore.Doris -Version 0.1.0-beta.1
<PackageReference Include="EntityFrameworkCore.Doris" Version="0.1.0-beta.1" />
<PackageVersion Include="EntityFrameworkCore.Doris" Version="0.1.0-beta.1" />
<PackageReference Include="EntityFrameworkCore.Doris" />
paket add EntityFrameworkCore.Doris --version 0.1.0-beta.1
#r "nuget: EntityFrameworkCore.Doris, 0.1.0-beta.1"
#:package EntityFrameworkCore.Doris@0.1.0-beta.1
#addin nuget:?package=EntityFrameworkCore.Doris&version=0.1.0-beta.1&prerelease
#tool nuget:?package=EntityFrameworkCore.Doris&version=0.1.0-beta.1&prerelease
EntityFrameworkCore.Doris
EntityFrameworkCore.Doris is a community Entity Framework Core provider for Apache Doris, built on top of the Doris MySQL-compatible protocol through MySqlConnector.
The provider is intentionally OLAP-oriented. It aims to make EF Core useful for Doris table modeling, native Doris DDL, LINQ queries, and append-style writes, while rejecting relational features that do not fit Doris well.
This package is in early alpha. Expect API and translation behavior to evolve.
Getting Started
dotnet add package EntityFrameworkCore.Doris --prerelease
using Microsoft.EntityFrameworkCore;
await using var db = new AnalyticsContext();
var topPages = await db.PageViews
.Where(v => v.EventDate >= new DateOnly(2026, 1, 1))
.GroupBy(v => v.Path)
.Select(g => new { Path = g.Key, Views = g.Count() })
.OrderByDescending(x => x.Views)
.Take(10)
.ToListAsync();
public sealed class AnalyticsContext : DbContext
{
public DbSet<PageView> PageViews => Set<PageView>();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseDoris(
"Server=127.0.0.1;Port=9030;Database=analytics;User ID=root;Password=;");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<PageView>(entity =>
{
entity.HasKey(e => e.Id);
entity.HasDuplicateKey(e => new { e.EventDate, e.Path });
entity.DistributedByHash(e => e.UserId, buckets: 16);
entity.HasProperties(("replication_num", "1"));
});
}
}
public sealed class PageView
{
public long Id { get; set; }
public DateOnly EventDate { get; set; }
public long UserId { get; set; }
public string Path { get; set; } = "";
public long Views { get; set; }
}
Doris Table Shape
EntityFrameworkCore.Doris keeps the EF tracking key and the Doris table key separate. Use the normal EF Core key for identity/tracking, then configure the Doris table model explicitly:
modelBuilder.Entity<EventFact>(entity =>
{
entity.HasKey(e => e.Id);
entity.HasDuplicateKey(e => new { e.EventDate, e.UserId });
entity.HasUniqueKey(e => e.Id);
entity.HasAggregateKey(e => new { e.EventDate, e.UserId });
entity.DistributedByHash(e => e.UserId, buckets: 32);
entity.HasProperties(
("replication_num", "1"),
("enable_unique_key_merge_on_write", "true"));
});
The migration SQL generator emits Doris-native table DDL:
CREATE TABLE `event_facts` (
...
)
DUPLICATE KEY(`event_date`, `user_id`)
DISTRIBUTED BY HASH(`user_id`) BUCKETS 32
PROPERTIES(
"replication_num" = "1"
);
Supported Types
| Doris type | CLR type |
|---|---|
BOOLEAN |
bool |
TINYINT |
sbyte |
SMALLINT |
short |
INT, INTEGER |
int |
BIGINT |
long |
LARGEINT |
Int128, BigInteger |
FLOAT |
float |
DOUBLE |
double |
DECIMAL(p,s) |
decimal |
DATE |
DateOnly, DateTime |
DATETIME |
DateTime |
CHAR, VARCHAR(n), STRING |
string |
Complex Doris types are not implemented yet.
Current Status
Supported
UseDoris(...)with connection strings,MySqlConnection, orMySqlDataSource- LINQ query translation inherited from the current relational/MySQL-based query pipeline, with Doris-specific SQL generation being added incrementally
LIMIT/OFFSETquery paginationSaveChangesforINSERT- Batch insert SQL generation
EnsureDeleted()for database-level cleanup- EF Core migrations for native Doris
CREATE TABLE GenerateCreateScript()for explicit Doris DDL generation- Doris migration history table generation
- Doris table key, hash distribution, bucket count, and table properties annotations
Explicitly Not Supported
- Automatic schema creation APIs such as
EnsureCreated,HasTables, andCreateTables - Change-tracker
UPDATEandDELETE - EF Core schemas; use Doris databases instead
- Foreign keys
- EF unique constraints; use Doris table key configuration instead
- Sequences
- Generated/default/computed columns
- Concurrency tokens
- Navigation, owned, and complex property mapping
- Idempotent migration scripts
Unsupported features throw NotSupportedException early so the provider fails clearly instead of generating OLTP-shaped SQL for Doris.
Doris Version Notes
Older Doris builds such as doris-4.1.1-rc01 had an upstream planner wrong-result issue for UNION DISTINCT with an outer ORDER BY plus LIMIT/OFFSET over wide entity projections. This was a Doris optimizer bug rather than a provider translation bug.
EntityFrameworkCore.Doris does not inject a provider-specific ROW_NUMBER() workaround for that shape. The provider keeps the normal SQL translation path and relies on upgraded Doris builds instead of silently rewriting queries.
We re-ran the original repro on doris-4.1.3-rc02-7126cf65d96, both through raw SQL and through the EF Core functional tests, and the query returned the correct result with the expected ContactName branch-local sort key in EXPLAIN VERBOSE.
Migrations
The first migration surface focuses on Doris-native DDL:
dotnet ef migrations add InitialCreate
dotnet ef database update
Generated CREATE TABLE statements include key model, distribution, bucket count, and properties when configured through the fluent API.
EnsureCreated() is intentionally not supported. Doris schema creation is expected to go through migrations or explicit execution of GenerateCreateScript() output. EnsureDeleted() remains available as a database-level cleanup helper because it does not need to infer Doris table shape.
Testing
Normal build and unit tests:
dotnet build
dotnet test
Functional tests are skipped by default. To run them against a local Doris FE:
$env:DORIS_RUN_INTEGRATION = "1"
$env:DORIS_TEST_CONNECTION = "Server=127.0.0.1;Port=9030;User ID=root;Password=;"
dotnet test .\test\EFCore.Doris.FunctionalTests\EFCore.Doris.FunctionalTests.csproj
Building Packages
dotnet pack .\src\EFCore.Doris\EFCore.Doris.csproj -c Release -o .\artifacts\packages
The NuGet package id is EntityFrameworkCore.Doris; the assembly and root namespace remain EFCore.Doris.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.10 && <= 10.0.999)
- MySqlConnector (>= 2.6.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-beta.1 | 74 | 7/19/2026 |
| 0.1.0-alpha.1 | 59 | 7/18/2026 |