1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/dotnetchina-sharding-core

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

Английский | Китайский

ShardingCore

высокопроизводительное легковесное решение для шардинга таблиц и баз данных в efcore с поддержкой разделения чтения и записи.

  • нулевые зависимости
  • нулевые затраты на обучение
  • нулевого вмешательства

Сообщество партнеров и спонсоров

📚 Документация

китайская документация Github | английская документация Github

китайская документация Gitee | английская документация Gitee

Как выбрать версию

  • shardingcore последняя версия.efcoreверсия.x.x

  • первая версия это версия shardingcore

  • вторая версия это версия efcore

  • остальные версии используют последнюю версию

  • efcore8 использует shardingcore7.8.x.x

  • efcore7 использует shardingcore7.7.x.x

  • efcore6 использует shardingcore7.6.x.x

  • efcore5 использует shardingcore7.5.x.x

  • efcore3 использует shardingcore7.3.x.x

  • efcore2 использует shardingcore7.2.x.x

Abp.VNext、WTM、FURION

Внешние зависимости

До версии ShardingCore 6.7.0.0

Выпуск EF Core .NET .NET (Core)
6.x.x.x 6.0.0 net 6.0 6.0+
5.x.x.x 5.0.10 Standard 2.1 5.0+
3.x.x.x 3.1.18 Standard 2.0 2.0+
2.x.x.x 2.2.6 Standard 2.0 2.0+

После версии ShardingCore 6.7.0.0

Используйте условие компиляции с NetFramework нет

Выпуск EF Core .NET (Core)
6.7.0.0+ 6.x net6
6.7.0.0+ 5.x net5 или netstandard2.1
6.7.0.0+ 3.x netcoreapp3 или netstandard2.0
6.7.0.0+ 2.x netcoreapp2

Быстрый старт

5 шагов для реализации шардинга по месяцам и поддержки автоматического создания таблиц по месяцам

Шаг 1: Установите пакет

Выберите драйвер базы данных для efcore

# основной пакет
PM> Install-Package ShardingCore
# драйвер SQL Server
PM> Install-Package Microsoft.EntityFrameworkCore.SqlServer
# драйвер MySQL
#PM> Install-Package Pomelo.EntityFrameworkCore.MySql
# используйте другой драйвер базы данных, если он поддерживается efcore

Шаг 2: Запросите сущность

Запросите сущность заказа


    /// <summary>
    /// таблица заказов
    /// </summary>
    public class Order
    {
        /// <summary>
        /// идентификатор заказа
        /// </summary>
        public string Id { get; set; }
        /// <summary>
        /// идентификатор плательщика
        /// </summary>
        public string Payer { get; set; }
        /// <summary>
        /// сумма платежа центами
        /// </summary>
        public long Money { get; set; }
        /// <summary>
        /// регион
        /// </summary>
        public string Area { get; set; }
        /// <summary>
        /// статус заказа
        /// </summary>
        public OrderStatusEnum OrderStatus { get; set; }
        /// <summary>
        /// время создания
        /// </summary>
        public DateTime CreationTime { get; set; }
    }
    public enum OrderStatusEnum
    {
        NotPaid = 1,
        Paying = 2,
        Paid = 3,
        PaymentFailed = 4
    }

Шаг 3: Создайте DbContext

Создайте MyDbContext, расширяющий AbstractShardingDbContext, тогда этот контекст поддерживает шардинг базы данных, если вы хотите поддержать шардинг таблиц (например, order_202101, order_202102, order_202103...), вам нужно реализовать IShardingTableDbContext


    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>();
                // настоящее имя таблицы Order_202101, Order_202102, Order_202103...
                entity.ToTable(nameof(Order));
            });
        }
        /// <summary>
        /// пустое выполнение, если используется шардинг таблиц
        /// </summary>
        public IRouteTail RouteTail { get; set; }
    }

Шаг 4: Создайте маршрут для отображения имени таблицы при запросе данных (Order)

// Конструктор маршрута поддерживает внедрение зависимостей, то есть область жизни является `Singleton`

    public class OrderVirtualTableRoute : AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute<Order>
    {
        //private readonly IServiceProvider _serviceProvider;

        //public OrderVirtualTableRoute(IServiceProvider serviceProvider)
        //{
            //_serviceProvider = serviceProvider;
        //}
        /// <summary>
        /// фиксированное значение, не использовать DateTime.Now, так как при перезапуске приложения это значение может измениться
        /// </summary>
        /// <returns></returns>
        public override DateTime GetBeginTime()
        {
            return new DateTime(2021, 1, 1);
        }
        /// <summary>
        /// настройте свойство шардинга
        /// </summary>
        /// <param name="builder"></param>

        public override void Configure(EntityMetadataTableBuilder<Order> builder)
        {
            builder.ShardingProperty(o => o.CreationTime);
        }
        /// <summary>
        /// включите задачу автоматической генерации таблиц
        /// </summary>
        /// <returns></returns>

        public override bool AutoCreateTableByTime()
        {
            return true;
        }
    }

Шаг 5: Настройте запуск

Необходимо изменить второй параметр метода AddDefaultDataSource(строка подключения), не изменяйте параметры делегата UseShardingQuery и UseShardingTransaction


        public void ConfigureServices(IServiceCollection services)
        {

            // настройки шардинга
            services.AddShardingDbContext<MyDbContext>()
                .UseRouteConfig(op =>
                {
                    op.AddShardingTableRoute<OrderVirtualTableRoute>();
                }).UseConfig(op =>
                {
                    op.UseShardingQuery((connStr, builder) =>
                    {
                        // connStr — входящий параметр делегата
                        builder.UseSqlServer(connStr);
                    });
                    op.UseShardingTransaction((connection, builder) =>
                    {
                        // connection — входящий параметр делегата
                        builder.UseSqlServer(connection);
                    });
                    // используйте вашу строку подключения к базе данных
                    op.AddDefaultDataSource(Guid.NewGuid().ToString("n"),
                        "Data Source=localhost;Initial Catalog=EFCoreShardingTableDB;Integrated Security=True;");
                }).AddShardingCore();
        }
```        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            // Необязательно, включение проверки отсутствующих таблиц и автоматической генерации
            app.ApplicationServices.UseAutoTryCompensateTable();
            // Другие настройки...
        }

Если EFCore поддерживает шардинг таблиц, как Sharding-JDBC в Java, вы можете радостно программировать на EFCore

[Route("api/[controller]")]
public class ValuesController : Controller
{
        private readonly MyDbContext _myDbContext;

        public ValuesController(MyDbContext myDbContext)
        {
            _myDbContext = myDbContext;
        }

        [HttpGet]
        public async Task<IActionResult> Get()
        {
            
            //_myDbContext.Add(order);
            //_myDbContext.Update(order);
            //_myDbContext.Remove(order);
            //_myDbContext.SaveChanges();
            var order = await _myDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Id == "2");
            return Ok(order);
        }
}

Производительность

Тестирование

  • на кэше компиляции выражений
  • версия ShardingCore x.3.1.63+
  • версия EFCore 6.0
  • идентификатор заказа является строкой, шардинг модуль (hashcode % 5)
  • N означает количество выполнений

Пример тестирования производительности

Пример производительности SQL Server 2012, строк данных 7734363 = 773w

// * Summary *

BenchmarkDotNet=v0.13.1, OS=Windows 10.0.18363.1500 (1909/November2019Update/19H2) AMD Ryzen 9 3900X, 1 CPU, 24 логических и 12 физических ядер .NET SDK=6.0.100 [Host] : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT DefaultJob : .NET 6.0.0 (6.0.21.52210), X64 RyuJIT

Метод N Среднее Ошибка Стандартное отклонение
NoShardingIndexFirstOrDefaultAsync 10 1.512 мс 0.0071 мс 0.0063 мс
ShardingIndexFirstOrDefaultAsync 10 1.567 мс 0.0127 мс 0.0113 мс

Описание использования

Все примеры ниже демонстрируются с использованием SQL Server. Код показывает примеры распределения таблиц, если требуется распределение баз данных, можно обратиться к Sample.SqlServerShardingDataSource.

Введение

Краткое описание библиотеки: все версии библиотеки основаны на номерах версий EF Core. Номер второй версии равный 2 указывает на поддержку только распределения баз данных, а номер более 3 указывает на поддержку как распределения баз данных, так и распределения таблиц. Библиотека разделена на две основные ветви: main и shardingTableOnly. Она поддерживает полностью настраиваемое распределение баз данных для 95% бизнес-потребностей, а также поддерживает распределение таблиц с использованием произвольной логики.

Концепция

Несколько ключевых концепций библиотеки:

Распределение баз данных
  • DataSourceName: имя источника данных для маршрутизации объектов к конкретному источнику данных.
  • IVirtualDataSource: виртуальный источник данных.
  • IVirtualDataSourceRoute: маршрут распределения баз данных.
Распределение таблиц
  • Хвост: окончание имени таблицы.
  • Предфикс хвоста: префикс хвоста, связь между названием таблицы и её хвостом.
  • Физическая таблица: реальная таблица в базе данных, название которой состоит из имени таблицы + TailPrefix + Tail.
  • Виртуальная таблица: абстрактная таблица, представляющая собой объединение всех физических таблиц.
  • Виртуальный маршрут: промежуточное звено между виртуальной и физической таблицами.

Преимущества

  • Поддержка пользовательского распределения баз данных.
  • Поддержка разделения чтения и записи.
  • Высокопроизводительное пагинация.
  • Поддержка ручного маршрутизации.
  • Поддержка массовых операций.
  • Поддержка пользовательских правил распределения таблиц.
  • Поддержка любого типа ключей для распределения таблиц.
  • Отсутствие затрат на обучение DbContext.
  • Поддержка соединений таблиц при распределении таблиц.
  • Поддержка использования EFCore.BulkExtensions для массовых операций.
  • Предоставление нескольких маршрутов по умолчанию для распределения таблиц.
  • Оптимизация для пагинации, поддерживающая низкопотребностное потоковое обработание больших страниц.

Недостатки

  • Распределение таблиц может увеличивать количество подключений при выполнении соединений между таблицами без возможности индексации до конкретной таблицы.

Установка

<PackageReference Include="ShardingCore" Version="5.LastVersion" />
или
<PackageReference Include="ShardingCore" Version="3.LastVersion" />
или
<PackageReference Include="ShardingCore" Version="2.LastVersion" />

Начало работы

Распределение таблиц

Пример использования модульного распределения таблиц для пользователя:

public class SysUserMod
{
    /// <summary>
    /// ID пользователя для распределения таблиц
    /// </summary>
    public string Id { get; set; }

    /// <summary>
    /// Имя пользователя
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Возраст пользователя
    /// </summary>
    public int Age { get; set; }
}

Создание виртуального маршрута:

public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualRoute<SysUserMod>
{
    // Длина хвоста: 00, 01, 02......99
    // Хэш-код % 3: [0, 1, 2]
    public SysUserModVirtualTableRoute() : base(2, 3)
    {
    }

    public override void Configure(EntityMetadataTableBuilder<SysUserMod> builder)
    {
        builder.ShardingProperty(o => o.Id);
    }
}

Для использования распределения таблиц необходимо создать контекст баз данных, который наследует от IShardingTableDbContext и реализует IShardingDbContext. По умолчанию предоставляется AbstractShardingDbContext.

``````markdown
  //DefaultTableDbContext является фактическим контекстом выполнения
    public class DefaultShardingDbContext : AbstractShardingDbContext, IShardingTableDbContext
    {
        public DefaultShardingDbContext(DbContextOptions<DefaultShardingDbContext> options) : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.ApplyConfiguration(new SysUserModMap());
        }
        public IRouteTail RouteTail { get; set; }

    }

Startup.cs в методе ConfigureServices(IServiceCollection services)

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            // если вы хотите использовать операцию без шардинга
            // services.AddDbContext<DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDB;Integrated Security=True"));
```### Операции с базой данных

#### Добавление записей в контекст базы данных
```csharp
_defaultShardingDbContext.AddRange(userMods);
await _defaultShardingDbContext.SaveChangesAsync();

Получение всех записей

public async Task ToList_All()
{
    var mods = await _defaultShardingDbContext.Set<SysUserMod>().ToListAsync();
    Assert.Equal(1000, mods.Count);
}
```    var modOrders1 = await _defaultShardingDbContext.Set<SysUserMod>().OrderBy(o => o.Age).ToListAsync();
    int ascAge = 1;
    foreach (var sysUserMod in modOrders1)
    {
        Assert.Equal(ascAge, sysUserMod.Age);
        ascAge++;
    }

    var modOrders2 = await _defaultShardingDbContext.Set<SysUserMod>().OrderByDescending(o => o.Age).ToListAsync();
    int descAge = 1000;
    foreach (var sysUserMod in modOrders2)
    {
        Assert.Equal(descAge, sysUserMod.Age);
        descAge--;
    }
}

Более сложные операции можно найти в юнит тестах

API методы

Метод Описание
ToListAsync Возвращает все записи
FirstOrDefaultAsync Возвращает первую найденную запись
MaxAsync Возвращает максимальное значение поля
MinAsync Возвращает минимальное значение поля
AnyAsync Проверяет наличие записей
CountAsync Возвращает количество записей
LongCountAsync Возвращает количество записей как long
SumAsync Возвращает сумму значений поля
AverageAsync Возвращает среднее значение поля
ContainsAsync Проверяет наличие значения в поле
GroupByAsync Группирует записи

По умолчанию используется маршрутизация по таблицам

Абстрактные маршрутизаторы

Абстракция Описание
AbstractSimpleShardingModKeyIntVirtualTableRoute Маршрутизация по модулю целого числа
AbstractSimpleShardingModKeyStringVirtualTableRoute Маршрутизация по модулю строки
AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute Маршрутизация по времени (дата и время)
AbstractSimpleShardingDayKeyLongVirtualTableRoute Маршрутизация по времени (timestamp)
AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute Маршрутизация по неделе (дата и время)
AbstractSimpleShardingWeekKeyLongVirtualTableRoute Маршрутизация по неделе (timestamp)
AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute Маршрутизация по месяцу (дата и время)
AbstractSimpleShardingMonthKeyLongVirtualTableRoute Маршрутизация по месяцу (timestamp)
AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute Маршрутизация по году (дата и время)
AbstractSimpleShardingYearKeyLongVirtualTableRoute Маршрутизация по году (timestamp)

Пример использования маршрутизатора

public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUserMod>
{
    protected override bool EnableHintRoute => true;

    public SysUserModVirtualTableRoute() : base(2, 3)
    {
    }
}

using (_shardingRouteManager.CreateScope())
{
    _shardingRouteManager.Current.TryCreateOrAddMustTail<SysUserMod>("00");

    var mod00s = await _defaultTableDbContext.Set<SysUserMod>().Skip(10).Take(11).ToListAsync();
}

Автоматическое создание таблиц

Пример автоматического создания таблиц

Транзакции

  1. Поддержка транзакций при вызове SaveChangesAsync
await _defaultShardingDbContext.SaveChangesAsync();
  1. Ручной запуск транзакций
using (var tran = _defaultTableDbContext.Database.BeginTransaction())
{
    ...
    _defaultTableDbContext.SaveChanges();
    tran.Commit();
}

Булк операции

var list = new List<SysUserMod>();

var dbContexts = _defaultTableDbContext.BulkShardingEnumerable(list);

foreach (var dataSourceMap in dbContexts)
{
    foreach (var tailMap in dataSourceMap.Value)
    {
        tailMap.Key.BulkInsert(tailMap.Value.ToList());
        //tailMap.Key.BulkDelete(tailMap.Value.ToList());
        //tailMap.Key.BulkUpdate(tailMap.Value.ToList());
    }
}

_defaultTableDbContext.SaveChanges();

//или использовать транзакцию
using (var tran = _defaultTableDbContext.Database.BeginTransaction())
{
    foreach (var dataSourceMap in dbContexts)
    {
        foreach (var tailMap in dataSourceMap.Value)
        {
            tailMap.Key.BulkInsert(tailMap.Value.ToList());
            //tailMap.Key.BulkDelete(tailMap.Value.ToList());
            //tailMap.Key.BulkUpdate(tailMap.Value.ToList());
        }
    }
    _defaultTableDbContext.SaveChanges();
    tran.Commit();
}

Чтение и запись

Поддерживается разделение чтения и записи между основным сервером и несколькими репликами.

Настройка контекста базы данных

services.AddShardingDbContext<DefaultShardingDbContext>((conStr, builder) => builder.UseSqlServer(conStr).UseLoggerFactory(efLogger)).Begin(o =>
{
    o.CreateShardingTableOnStart = true;
    o.EnsureCreatedWithOutShardingTable = true;
}).AddShardingTransaction((connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger)).AddDefaultDataSource("ds0", "Data Source=localhost;Initial Catalog=ShardingCoreDB1;Integrated Security=True;").AddShardingTableRoute(o => { o.AddShardingTableRoute<SysUserModVirtualTableRoute>(); }).AddReadWriteSeparation(o => { return new Dictionary<string, ISet<string>>() { { "ds0", new HashSet<string>() { "Data Source=localhost;Initial Catalog=ShardingCoreDBReadOnly1;Integrated Security=True;", "Data Source=localhost;Initial Catalog=ShardingCoreDBReadOnly2;Integrated Security=True;" } }; }; }, ReadStrategyEnum.Loop, defaultEnable: true).End();
                # решает проблему задержки чтения/записи данных при отсутствии данных
                # dbcontext использует соединение с базой данных для записи
            _virtualDbContext.ReadWriteSeparationWriteOnly();

Высокопроизводительная пагинация

sharding-core сам использует потоковое обработание для получения данных, в обычной ситуации и для одного таблицы разница практически незаметна. Однако при использовании пагинации с пропуском X страниц производительность будет снижаться пропорционально увеличению X (O(n)). В настоящее время этот фреймворк реализовал высокопроизводительную пагинацию, которая может быть настроена по запросу пользователя для выполнения функции пагинации.

Поддерживаемые версии x.2.0.16+1. Как включить конфигурацию пагинации? Например, если мы хотим настроить пагинацию для месячного журнала зарплат пользователей, нам следует реализовать интерфейс IPaginationConfiguration<>.

public class SysUserSalaryPaginationConfiguration : IPaginationConfiguration<SysUserSalary>
{
    public void Configure(PaginationBuilder<SysUserSalary> builder)
    {
        builder.PaginationSequence(o => o.Id)
            .UseRouteCompare(Comparer<string>.Default)
            .UseQueryMatch(PaginationMatchEnum.Owner | PaginationMatchEnum.Named | PaginationMatchEnum.PrimaryMatch);
        builder.PaginationSequence(o => o.DateOfMonth)
            .UseQueryMatch(PaginationMatchEnum.Owner | PaginationMatchEnum.Named | PaginationMatchEnum.PrimaryMatch).UseAppendIfOrderNone(10);
        builder.PaginationSequence(o => o.Salary)
            .UseQueryMatch(PaginationMatchEnum.Owner | PaginationMatchEnum.Named | PaginationMatchEnum.PrimaryMatch).UseAppendIfOrderNone();
        builder.ConfigReverseShardingPage(0.5d, 10000L);
    }
}
  1. Добавление конфигурации Добавьте конфигурацию в соответствующий маршрут пользователя.
public override IPaginationConfiguration<SysUserSalary> CreatePaginationConfiguration()
{
    return new SysUserSalaryPaginationConfiguration();
}
  1. Что значит внутри метода Configure?
  1. builder.PaginationSequence(o => o.Id) — это конфигурация поля Id как ключа для пагинации. Правила сравнения маршрута задаются через UseRouteCompare. Это позволяет оптимизировать выборку данных, когда используется поле Id для сортировки.
  2. UseQueryMatch указывает правила соответствия запроса, такие как наличие поля Owner, Named или PrimaryMatch.
  3. builder.ConfigReverseShardingPage — это конфигурация обратного порядка пагинации, что помогает улучшить производительность при большом количестве пропущенных записей.
  1. Как использовать пагинацию?
var shardingPageResultAsync = await _defaultTableDbContext.Set<SysUserMod>().OrderBy(o => o.Age).ToShardingPageAsync(pageIndex, pageSize);

Внимание: Если вы сортируете данные по времени, рекомендуется включить обратное сортирование и добавить сортировку по времени. Если вы используете модульное распределение или пользовательскую пагинацию, лучше всего использовать Id для сортировки и добавить обратное сортирование для повышения производительности.

Кэширование выражений

Вы можете включить кэширование выражений через маршрут для кэширования выражений для каждого tail. Поддерживаются операторы =, >, >=, <, <=, equal.

public class OrderCreateTimeVirtualTableRoute : AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute<Order>
{
    // Включение кэширования выражений
    public override bool EnableRouteParseCompileCache => true;
}

Для кэширования выражений можно переопределить родительский метод или реализовать его самостоятельно.

public virtual Func<string, bool> CachingCompile(Expression<Func<string, bool>> parseWhere)
{
    if (EnableRouteParseCompileCache)
    {
        var doCachingCompile = DoCachingCompile(parseWhere);
        if (doCachingCompile != null)
            return doCachingCompile;
        doCachingCompile = CustomerCachingCompile(parseWhere);
        if (doCachingCompile != null)
            return doCachingCompile;
    }
    return parseWhere.Compile();
}

protected virtual Func<string, bool> DoCachingCompile(Expression<Func<string, bool>> parseWhere)
{
    var shouldCache = ShouldCache(parseWhere);
    if (shouldCache)
        return _routeCompileCaches.GetOrAdd(parseWhere, key => parseWhere.Compile());
    return null;
}

protected virtual Func<string, bool> CustomerCachingCompile(Expression<Func<string, bool>> parseWhere)
{
    return null;
}

Кэширование выражений может повысить производительность компиляции маршрутов до 10 раз.

Важные моменты

При использовании этого фреймворка важно отметить следующие моменты:

  • Если ваш ShardingDbContext переопределяет следующие службы, они могут не работать корректно. Чтобы восстановить работу, вам потребуется переопределить их самостоятельно.
  • Шаблон ShardingDbContext
return optionsBuilder.UseShardingWrapMark()
    .ReplaceService<IDbSetSource, ShardingDbSetSource>()
    .ReplaceService<IQueryCompiler, ShardingQueryCompiler>()
    .ReplaceService<IDbContextTransactionManager, ShardingRelationalTransactionManager<TShardingDbContext>>()
    .ReplaceService<IRelationalTransactionFactory, ShardingRelationalTransactionFactory<TShardingDbContext>>();
  • Шаблон DefaultDbContext
return optionsBuilder.ReplaceService<IModelCacheKeyFactory, ShardingModelCacheKeyFactory>()
    .ReplaceService<IModelCustomizer, ShardingModelCustomizer<TShardingDbContext>>();

Фреймворк использует AppDomain.CurrentDomain.GetAssemblies(), что может вызвать проблемы с загрузкой сборок. Поэтому рекомендуется загружать необходимые DLL на уровне API. При использовании фреймворка убедитесь, что:

  • Объекты с разделённой таблицей наследуются от IShardingTable
  • Объекты с разделённой таблицей имеют ShardingKey
  • Объекты с разделённым источником данных наследуются от IShardingDataSource
  • Объекты с разделённым источником данных имеют ShardingDataSourceKey
  • Объекты уже имеют реализованное виртуальное направление
  • Startup уже имеет добавленное виртуальное направление
  • Startup уже имеет добавленный Bootstrapper.Start()
// Поддерживает окончательное изменение
var sresult = _defaultTableDbContext.Set<SysUserMod>().ToList();

var sysUserMod98 = result.FirstOrDefault(o => o.Id == "98");
sysUserMod98.Name = "name_update" + new Random().Next(1, 99) + "_98";
await _defaultTableDbContext.SaveChangesAsync();
-- лог информации
Executed DbCommand (1ms) [Parameters=[@p1='?' (Size = 128), @p0='?' (Size = 128)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [SysUserMod_02] SET [Name] = @p0
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

Планы

  • [Создание официального сайта, если проект будет успешным]
  • [Разработка более полной документации]
  • [Переработка для поддержки других ORM .NET]

Последнее

Этот фреймворк был создан, применив идеи многих существующих систем разделения таблиц. На данный момент все предоставляемые интерфейсы реализованы и поддерживают запросы между таблицами. Для пагинации также используются потоковые запросы, чтобы избежать взрывного использования памяти при пропуске больших объемов данных. Этот библиотека ещё находится в начальной стадии развития и требует доработки, поэтому прошу понимания. Если вам понравился проект, я буду рад получить звезду.

Этот документ был подготовлен ночью, надеюсь он поможет привлечь больше внимания к проекту. Также я очень ценю возможность общаться и делиться опытом.

Благодаря множеству открытых проектов и идей была создана эта система, и я надеюсь, что она сможет сделать свой вклад в развитие экосистемы .NET. Я буду продолжать поддерживать этот проект долгое время. Если вы являетесь экспертом в этой области, я буду рад сотрудничеству.

Донат

АлиPay WeChatPay Блог

QQ группа: 771630778

Личный QQ: 326308290 (добро пожаловать для техподдержки)

Личная почта: 326308290@qq.com

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Описание недоступно Развернуть Свернуть
C#
Apache-2.0
Отмена

Обновления (101)

все

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/dotnetchina-sharding-core.git
git@api.gitlife.ru:oschina-mirror/dotnetchina-sharding-core.git
oschina-mirror
dotnetchina-sharding-core
dotnetchina-sharding-core
main