Furion sub table sub database I also want happy coding

Keywords: dotNETCore sharding

Furion sub table and sub database integration ShardingCore

ShardingCore

ShardingCore is easy to use, simple, high-performance and universal. It is an extended solution for tables and databases under the efcore ecosystem. It supports all versions of efcore2 +, all databases of efcore2 +, custom routing, dynamic routing, high-performance paging and read-write separation, If you like this component or it is helpful to you, please click distribute star so that more. Neters can see and use it

Github Star Help dotnet ecology Gitee Star

background

With the release of. net6, successive frameworks have begun to be supported, and ShardingCore is no exception. In order to promote the. net ecology and let more people know that there are table and database solutions under. net, we intend to write an article on the integration of ShardingCore into other frameworks.

Fourin We should also be clear about the framework. The author is also a person who is willing to open source and has the spirit of open source. We all love open source, so we decided to help Fourier (rub the heat). After AbpVNext's "perfect" ShardingCore integration last time, this time it brings ShardingCore integration under Furion.

The perfect sub table and sub library solution under efcore supports the integration framework of any efcore. It can be perfectly supported or needs to be modified slightly. It doesn't need to let you have any learning cost. It can make your program perfectly support sub table and sub library without modifying the existing efcore code. Truly achieve "zero" code modification.

New Furion project

First, we have taken the latest version of Furion as an example v3.0.5 to create a new net6 project of an empty aspnetcore web api. Of course, we also support all aspnetcore versions of efcore2 +.

Then we add ShardingCore and efcore.SqlServer packages

New dbcontext

Here's how Furion uses it. Like Abp, it needs to inherit its own DbContext called AppDbContext, but it doesn't matter. Because ShardingCore is implemented based on the interface, there is no multi inheritance problem, but we need to implement the source code address of the abstract version of Furion's ShardingDbContext AppShardingDbContext

To put it simply, if you need to inherit a dbcontext, you need to implement three interfaces: ishardingdbcontext, isupportshardingtransaction and isupportshardingreadwrite. They are the core interfaces of sub tables and sub databases, supporting transactions and separation of read and write.

The concrete has helped you abstract. Just copy the code.

When we are ready, we start to create a new dbcontext

[AppDbContext("SqlServerConnectionString", DbProvider.SqlServer)]
public class DefaultDbContext : AppShardingDbContext<DefaultDbContext>,IShardingTableDbContext
{
    public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)
    {
    }

    public IRouteTail RouteTail { get; set; }
}

Create todoitem object

public class TodoItem:IPrivateEntity
{
    public string Id { get; set; }
    public string Name { get; set; }
}

  

Here, we make the Id of TodoItem into a module splitting table

Configure dbcontext

[AppDbContext("SqlServerConnectionString", DbProvider.SqlServer)]
public class DefaultDbContext : AppShardingDbContext<DefaultDbContext>,IShardingTableDbContext
{
    public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)
    {
    }

    public IRouteTail RouteTail { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<TodoItem>(entity =>
        {
            entity.HasKey(o => o.Id);
            entity.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(50).HasComment("Id");
            entity.Property(o => o.Name).IsRequired().HasMaxLength(50).HasComment("name");
            entity.ToTable(nameof(TodoItem));
        });
    }
}

  

The simple configuration of todoitem is configured. Note that this configuration is not necessary here. You can also use Attribute+DbSet or fluent API

Create table routing for TodoItem

public class TodoItemVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<TodoItem>
{
    public TodoItemVirtualTableRoute() : base(2, 8)
    {
    }
    public override void Configure(EntityMetadataTableBuilder<TodoItem> builder)
    {
        builder.ShardingProperty(x => x.Id);
    }
}

Here, the module is simply taken and passed in through the constructor. For details, please refer to the document. The sub table suffix is 2 digits. Module 8 is 00,01..... 07. There are 8 tables in total. Shardingproperty (x = > x.Id) means that the sub table field of TodoItem is Id.

Note: This is just for simple demonstration. If you need external input, you can implement it by implementing AbstractShardingOperatorVirtualTableRoute, and the route constructor supports dependency injection of singleton

Initialize Furion configuration

AppStartup

[AppStartup(600)]
public sealed class SqlServerEntityFrameworkCoreStartup : AppStartup
{
    public static readonly ILoggerFactory efLogger = LoggerFactory.Create(builder =>
    {
        builder.AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information).AddConsole();
    });
    public void ConfigureServices(IServiceCollection services)
    {
        var connStr = DbProvider.GetConnectionString<DefaultDbContext>(/*Not here*/);
        // Configure database context and support N databases
        services.AddDatabaseAccessor(options =>
        {
            // Configure default database
            options.AddDb<DefaultDbContext>(o =>
            {
                o.UseSqlServer(connStr).UseSharding<DefaultDbContext>().UseLoggerFactory(efLogger);
            });

        });
        services.AddShardingConfigure<DefaultDbContext>((s, builder) =>
        {
            builder.UseSqlServer(s).UseLoggerFactory(efLogger);
        }).Begin(o =>
        {
            o.CreateShardingTableOnStart = true;
            o.EnsureCreatedWithOutShardingTable = true;
            o.AutoTrackEntity = true;
        })
             .AddShardingTransaction((connection, builder) =>
                 builder.UseSqlServer(connection).UseLoggerFactory(efLogger))
             .AddDefaultDataSource("ds0", connStr)
             .AddShardingTableRoute(o =>
             {
                 o.AddShardingTableRoute<TodoItemVirtualTableRoute>();
             }).End();
    }
}

Through the official website, we can know how to configure the efcore for Furion. At present, the sharding core does not support the single instance dbcontext of the efcore, so it is not recommended to use the single instance.

Additional configuration:. Usesharding < defaultdbcontext > () you only need to configure dbcontext and use sharding. You can ignore all the original dbcontext injections

Sharding core configuration: AddShardingConfigure is an additional configuration of sharding core based on efcore to support the expansion of tables and databases. For more configurations, please refer to file

Program

using ShardingCore.Bootstrapers;

var builder = WebApplication.CreateBuilder(args).Inject();

// Add services to the container.

builder.Services.AddControllers().AddInject();

var app = builder.Build();

// Configure the HTTP request pipeline.

app.UseAuthorization();

app.UseInject();
app.Services.GetRequiredService().Start();
app.MapControllers();

app.Run();
Note: many students always forget to start, which makes sharding core unable to use app. Services. Getrequiredservice < ishardingbootstrapper > (). Start();  

Write controller

First, we inject the constructor irepository < todoitem > todoitemrepository, which is provided by Furion

Secondly, we write the add, delete, modify and query interface

    [HttpGet]
    public async Task<IActionResult> Add()
    {
        await _todoItemRepository.InsertAsync(new TodoItem() { Id = Guid.NewGuid().ToString("n"), Name = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") });
        await _todoItemRepository.SaveNowAsync();
        return Ok();
    }
    [HttpGet]
    public async Task<IActionResult> List()
    {
        var list = await _todoItemRepository.AsQueryable().ToListAsync();
        return Ok(list);
    }
    [HttpGet]
    public async Task<IActionResult> First([FromQuery]string id)
    {
        var todoItem = await _todoItemRepository.FirstOrDefaultAsync(o => o.Id == id);
        return Ok(todoItem);
    }
    [HttpGet]
    public async Task<IActionResult> Update([FromQuery]string id)
    {
        var todoItem = await _todoItemRepository.FirstOrDefaultAsync(o => o.Id == id);
        todoItem.Name = "123";
        await _todoItemRepository.SaveNowAsync();
        return Ok(todoItem);
    }

Start project

Because the ShardingCore is configured for testing by default

o.CreateShardingTableOnStart = true;
o.EnsureCreatedWithOutShardingTable = true;
So the startup will help us build tables and databases

newly added

Table inserted into specific hash%8 as expected

Query all

Because it is to obtain all the sub tables, all the sub tables will be queried here to meet the expectations

Get single

Get the expected id module for a single entry, so using id to query will find the specified table

to update

Meet the expected code, first query table 05, update table 05, and use tracking update

Let's check again to see if it has been really modified

So far, our Furion ShardingCore integration has been completed. Of course, this is just the tip of the iceberg of ShardingCore. The simplest sub table. If you like or think ShardingCore is useful, can you give a praise or star? Kaiyuan authors hope that their open source projects will be directed and improved by more experts. I also hope to make a modest contribution to the sub table and sub database under. net. Under efcore, I believe ShardingCore is the most perfect solution without official support for efcore. The whole code experience is 0-aware. As long as you configure it, you don't need to consider it at all. Of course, some students want to use it. If I want to specify some tables in some cases, ShardingCore also supports it. Therefore, it is the best table and database splitting scheme for "zero" intrusion business code under automatic conditions. Please query for more usage methods

github ShardingCore documentation

gitee ShardingCore documentation

Finally, the project source code

FurionShardingDemo

dotnet is the best in the world (roaring)

Table and database component praise star

Blog

QQ group: 771630778

Personal QQ: 326308290 (welcome technical support to provide your valuable opinions)

Personal email: 326308290@qq.com

Posted by Nat on Wed, 24 Nov 2021 01:05:26 -0800