# ShardingCore adds table and database sharding to EF Core without rewriting queries

> ShardingCore is an Entity Framework Core extension that routes entities to sharded tables and sharded databases, with read-write separation, and claims zero dependency, zero learning cost and zero intrusion into business code. The cost is a routing concept you have to model explicitly, and a version number that encodes the EF Core release you target.

**dotnetcore/sharding-core** — high performance lightweight solution for efcore sharding table and sharding database support read-write-separation .一款ef-core下高性能、轻量级针对分表分库读写分离的解决方案，具有零依赖、零学习成本、零业务代码入侵

- Repository: https://github.com/dotnetcore/sharding-core
- Website: https://xuejmnet.github.io/sharding-core-doc/
- Stars: 1,287 · Forks: 182
- Language: C#
- License: Apache-2.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/dotnetcore-sharding-core

## Sharding is expressed in route classes, not in the queries

The pitch of the project is a solution for EF Core sharded tables and sharded databases with read-write separation, described as zero dependency, zero learning cost and zero incursion into business code. The mechanism behind the third claim is the route abstraction. A route class implements an interface that maps an entity to a table name and, for database level sharding, to a data source. Your queries never mention a table name, so the business code keeps working on a logical entity while the route decides which physical table or database serves it. The route constructor supports dependency injection, and the documentation notes that its lifetime scope is singleton, which matters because the route holds the mapping configuration for the whole application.

## A monthly table route is the demonstrated case

The worked example in the documentation is a table per month, with tables named `Order_202101`, `Order_202102` and so on. The route class derives from `AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute<Order>`, which supplies the month arithmetic, and the developer supplies two things. The first is the begin time, and the example returns a fixed `new DateTime(2021, 1, 1)`, with a comment that explains why: a fixed value, because using `DateTime.Now` would change the value whenever the application restarts. That is the single most important detail in the whole example. A route whose boundary moves on every restart will silently misroute rows across a table boundary, so the boundary has to be data, not clock state. The second is the `Configure` override, where the sharding property is set on the entity metadata builder. The quick start describes five steps to implement sharding by month with automatic table creation by month.

## The DbContext picks up sharding through its base class and interface

The context is where the two sharding modes are separated. A context that extends `AbstractShardingDbContext` supports sharding databases. To also get sharded tables, the context additionally implements `IShardingTableDbContext`, and the interface has a single member, a `RouteTail` property, which the documentation describes as an empty implementation when you use sharding tables. The entity configuration in `OnModelCreating` looks like ordinary EF Core code, with keys, required properties, unicode flags, maximum lengths and a conversion for the enum, and the table name is set with `entity.ToTable(nameof(Order))` while a comment records that the real table names are the monthly ones:

```csharp
    public class MyDbContext:AbstractShardingDbContext,IShardingTableDbContext
    {
        public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Order>(entity =>
            {
                entity.HasKey(o => o.Id);
                entity.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(50);
                entity.Property(o=>o.Payer).IsRequired().IsUnicode(false).HasMaxLength(50);
                entity.Property(o => o.Area).IsRequired().IsUnicode(false).HasMaxLength(50);
                entity.Property(o => o.OrderStatus).HasConversion<int>();
                //really table name is Order_202101,Order_202102,Order_202103.....
                entity.ToTable(nameof(Order));
            });
        }
        /// <summary>
        /// empty implment if use sharding table
        /// </summary>
        public IRouteTail RouteTail { get; set; }
    }
```

The entity itself is a plain class with plain properties, which is the clearest evidence for the no intrusion claim: the `Order` class has no attributes and no sharding knowledge at all.

## The package version encodes your EF Core major version

The versioning scheme is the first thing to understand before you install anything, because picking the wrong branch is the most likely mistake. The format is `shardingcore.<efcoreversion>.x.x`, where the first number is the ShardingCore version, the second is the EF Core version, and the rest is the patch line. The mapping is direct: EF Core 10 uses the 7.10.x.x line, EF Core 9 uses 7.9.x.x, EF Core 8 uses 7.8.x.x, down through EF Core 2 using 7.2.x.x. Older releases were different: before version 6.7.0.0 the 6.x.x.x line targeted EF Core 6.0.0 on net6, 5.x.x.x targeted EF Core 5.0.10 on Standard 2.1, and 3.x.x.x and 2.x.x.x targeted Standard 2.0. After 6.7.0.0 the packages are compiled with a condition rather than for .NET Framework. The most recent tags are 7.x.2.2 from 2026-07-29, 7.x.2.1 from 2026-02-19 and 7.x.1.23 from 2025-01-15, and the last push to the main branch was on 2026-09-10.

## Choosing the driver is step one of the quick start

The installation step asks you to pick a database driver for EF Core and install the base package alongside it. The package manager commands are given for the base package, for the SQL Server driver, and, commented out, for the MySQL driver, with a note that any driver EF Core supports can be used:

```shell
# basic package[README-zh.md](README-zh.md)
PM> Install-Package ShardingCore
# sqlserver driver
PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer
# mysql driver
#PM> Install-Package Pomelo.EntityFrameworkCore.MySql
# use other database driver,if efcore support
```

The samples directory shows how wide the supported surface is in practice. It includes a `Sample.SqlServer`, a `Sample.MySql`, a `Sample.MySQLDataSourceOnly`, a `Sample.ShardingConsole`, a `Sample.AutoCreateIfPresent`, a `Sample.Migrations`, a `Sample.MultiConfig`, a `Sample.NoShardingMultiLevel`, a `Sample.OracleIssue`, a `Sample.SqlServer3x` for the older three line context, a `Sample.SqlServerShardingTable`, a `Sample.SqlServerShardingDataSource` and a `Sample.SqlServerShardingAll`, plus samples for ABP sharding, for automatic sharding by date on SQL Server, and a dynamic Npgsql one. The Oracle entry and the 3.x entry are worth noting because they are the two cases most likely to surprise you.

## Where the boundary of the approach sits

The design has a clear assumption: your data has a sharding key, usually a time, and the route maps it to a table or a database. If your queries need to span shards, the framework has to fan out and merge, and the documentation does not describe how that behaves in terms of cost. The `RouteTail` member, described as an empty implementation for the table case, also hints that the route model can be extended with a tail concept for more complex mappings, which is where a real project would look for guidance. The zero learning cost claim is about the business code, and it holds in the demonstrated case, but a route class with a fixed boundary date and a monthly key is still a piece of infrastructure a team has to own, especially if the shard count grows or the key changes. The project is published on NuGet as ShardingCore, hosted under Apache-2.0, with the documentation site at the project homepage and a Chinese version of the README in the repository, alongside samples, a benchmarks directory and separate `src` folders for the older target frameworks.

## Conclusion

Adopt ShardingCore if you already run EF Core and need sharded tables or read-write separation without rewriting your queries, since the routing is expressed in route classes and the query code stays as it is. Do not adopt it if your data model has no natural sharding key, because the routing model needs a key that decides the table, and a table per month driven by a clock is the case the documentation demonstrates. Verify first which package version matches your EF Core major version, since the numbering encodes it, and check the route's start time, because the example uses a fixed date rather than the current time for a reason the code comments explain.

## FAQ

### Which ShardingCore package version should I install?

The version number is `shardingcore.<efcoreversion>.x.x`, so the second number is your EF Core major version. EF Core 10 uses 7.10.x.x, EF Core 9 uses 7.9.x.x, EF Core 8 uses 7.8.x.x, and so on down to EF Core 2 using 7.2.x.x.

### How do I implement sharding by month with ShardingCore?

Create a route class deriving from `AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute`, return a fixed begin time from `GetBeginTime` rather than using the current time, and set the sharding property in the `Configure` override. The context then extends `AbstractShardingDbContext` and implements `IShardingTableDbContext`.

### What is the difference between AbstractShardingDbContext and IShardingTableDbContext?

A context extending `AbstractShardingDbContext` supports sharding databases. Implementing `IShardingTableDbContext` in addition is what enables sharded tables, and the interface has a single member, the `RouteTail` property, which the example leaves empty.

### Does ShardingCore require changes to my entity classes?

No. The `Order` entity in the quick start is a plain class with plain properties and no attributes. The sharding knowledge lives in the DbContext and in the route class, and the entity is configured in `OnModelCreating` with `entity.ToTable(nameof(Order))` while the real table names carry the month suffix.

### What licence is ShardingCore released under?

The project is published under the Apache-2.0 licence, with the licence file in the repository root. The package is distributed on NuGet under the name ShardingCore.

## Sources

- [dotnetcore/sharding-core on GitHub](https://github.com/dotnetcore/sharding-core)
- [License: Apache-2.0](https://github.com/dotnetcore/sharding-core/blob/main/LICENSE)
- [Project website](https://xuejmnet.github.io/sharding-core-doc/)
- [README](https://github.com/dotnetcore/sharding-core/blob/main/README.md)
- [Releases](https://github.com/dotnetcore/sharding-core/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/dotnetcore-sharding-core
