diff --git a/ShardingCore.sln b/ShardingCore.sln index b48288cb..643c587c 100644 --- a/ShardingCore.sln +++ b/ShardingCore.sln @@ -45,6 +45,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src5x", "src5x", "{EB1C9149 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShardingCore.5x", "src5x\ShardingCore.5x\ShardingCore.5x.csproj", "{68A9F118-EF0A-4D03-8845-77D084561A28}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.Migrations", "samples\Sample.Migrations\Sample.Migrations.csproj", "{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -111,6 +113,10 @@ Global {68A9F118-EF0A-4D03-8845-77D084561A28}.Debug|Any CPU.Build.0 = Debug|Any CPU {68A9F118-EF0A-4D03-8845-77D084561A28}.Release|Any CPU.ActiveCfg = Release|Any CPU {68A9F118-EF0A-4D03-8845-77D084561A28}.Release|Any CPU.Build.0 = Release|Any CPU + {648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -131,6 +137,7 @@ Global {E4DAA43A-B64D-45CF-81B8-7B8FD338D686} = {CC2C88C0-65F2-445D-BE78-973B840FE281} {0193E3CF-F2FD-449A-B2D5-7F68E551FDBF} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73} {68A9F118-EF0A-4D03-8845-77D084561A28} = {EB1C9149-78C9-4D99-BE3F-B80FE2015E96} + {648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8C07A667-E8B4-43C7-8053-721584BAD291} diff --git a/samples/Sample.BulkConsole/Program.cs b/samples/Sample.BulkConsole/Program.cs index 25a91faf..3e200b1e 100644 --- a/samples/Sample.BulkConsole/Program.cs +++ b/samples/Sample.BulkConsole/Program.cs @@ -82,7 +82,7 @@ namespace Sample.BulkConsole var queryable = myShardingDbContext.Set().Where(o => o.CreateTime >= b).OrderBy(o => o.CreateTime); var startNew1 = Stopwatch.StartNew(); - int skip = 0, take = 10; + int skip = 0, take = 1000; for (int i = 20000; i < 30000; i++) { skip = take * i; diff --git a/samples/Sample.Migrations/Controllers/WeatherForecastController.cs b/samples/Sample.Migrations/Controllers/WeatherForecastController.cs new file mode 100644 index 00000000..b8e2d9c7 --- /dev/null +++ b/samples/Sample.Migrations/Controllers/WeatherForecastController.cs @@ -0,0 +1,44 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Sample.Migrations.EFCores; + +namespace Sample.Migrations.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WeatherForecastController : ControllerBase + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + private readonly DefaultShardingTableDbContext _context; + + public WeatherForecastController(ILogger logger,DefaultShardingTableDbContext context) + { + _logger = logger; + _context = context; + } + + [HttpGet] + public IEnumerable Get() + { + _context.Database.Migrate(); + var rng = new Random(); + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateTime.Now.AddDays(index), + TemperatureC = rng.Next(-20, 55), + Summary = Summaries[rng.Next(Summaries.Length)] + }) + .ToArray(); + } + } +} diff --git a/samples/Sample.Migrations/DefaultDesignTimeDbContextFactory.cs b/samples/Sample.Migrations/DefaultDesignTimeDbContextFactory.cs new file mode 100644 index 00000000..e5dc02e3 --- /dev/null +++ b/samples/Sample.Migrations/DefaultDesignTimeDbContextFactory.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.Extensions.DependencyInjection; +using Sample.Migrations.EFCores; +using ShardingCore; + +namespace Sample.Migrations +{ + public class DefaultDesignTimeDbContextFactory: IDesignTimeDbContextFactory + { + static DefaultDesignTimeDbContextFactory() + { + var services = new ServiceCollection(); + services.AddShardingDbContext( + o => + o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBMigration;Integrated Security=True;") + .ReplaceService>() + ).Begin(o => + { + o.CreateShardingTableOnStart = true; + o.EnsureCreatedWithOutShardingTable = true; + o.AutoTrackEntity = true; + }) + .AddShardingQuery((conStr, builder) => builder.UseSqlServer(conStr) + .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)) + .AddShardingTransaction((connection, builder) => + builder.UseSqlServer(connection)) + .AddDefaultDataSource("ds0", + "Data Source=localhost;Initial Catalog=ShardingCoreDBMigration;Integrated Security=True;") + .AddShardingTableRoute(o => + { + o.AddShardingTableRoute(); + o.AddShardingTableRoute(); + }).End(); + services.AddLogging(); + var buildServiceProvider = services.BuildServiceProvider(); + ShardingContainer.SetServices(buildServiceProvider); + new ShardingBootstrapper(buildServiceProvider).Start(); + } + + public DefaultShardingTableDbContext CreateDbContext(string[] args) + { + var dbContextOptions = new DbContextOptionsBuilder().UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBMigration;Integrated Security=True;").Options; + return new DefaultShardingTableDbContext(dbContextOptions); + } + } +} diff --git a/samples/Sample.Migrations/EFCores/DefaultShardingTableDbContext.cs b/samples/Sample.Migrations/EFCores/DefaultShardingTableDbContext.cs new file mode 100644 index 00000000..29e15797 --- /dev/null +++ b/samples/Sample.Migrations/EFCores/DefaultShardingTableDbContext.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using ShardingCore.Sharding; + +namespace Sample.Migrations.EFCores +{ + public class DefaultShardingTableDbContext:AbstractShardingDbContext + { + public DefaultShardingTableDbContext(DbContextOptions options) : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + modelBuilder.ApplyConfiguration(new NoShardingTableMap()); + modelBuilder.ApplyConfiguration(new ShardingWithModMap()); + modelBuilder.ApplyConfiguration(new ShardingWithDateTimeMap()); + } + } +} diff --git a/samples/Sample.Migrations/EFCores/DefaultTableDbContext.cs b/samples/Sample.Migrations/EFCores/DefaultTableDbContext.cs new file mode 100644 index 00000000..01302166 --- /dev/null +++ b/samples/Sample.Migrations/EFCores/DefaultTableDbContext.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions; +using ShardingCore.Sharding.Abstractions; + +namespace Sample.Migrations.EFCores +{ + public class DefaultTableDbContext:DbContext,IShardingTableDbContext + { + public DefaultTableDbContext(DbContextOptions options):base(options) + { + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + modelBuilder.ApplyConfiguration(new NoShardingTableMap()); + modelBuilder.ApplyConfiguration(new ShardingWithModMap()); + modelBuilder.ApplyConfiguration(new ShardingWithDateTimeMap()); + } + + public IRouteTail RouteTail { get; set; } + } +} diff --git a/samples/Sample.Migrations/EFCores/NoShardingTable.cs b/samples/Sample.Migrations/EFCores/NoShardingTable.cs new file mode 100644 index 00000000..cf8a3315 --- /dev/null +++ b/samples/Sample.Migrations/EFCores/NoShardingTable.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace Sample.Migrations.EFCores +{ + public class NoShardingTable + { + public string Id { get; set; } + public string Name { get; set; } + public int Age { get; set; } + } + + public class NoShardingTableMap : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(128); + builder.Property(o => o.Name).HasMaxLength(128); + builder.ToTable(nameof(NoShardingTable)); + } + } +} diff --git a/samples/Sample.Migrations/EFCores/ShardingSqlServerMigrationsSqlGenerator.cs b/samples/Sample.Migrations/EFCores/ShardingSqlServerMigrationsSqlGenerator.cs new file mode 100644 index 00000000..f1233209 --- /dev/null +++ b/samples/Sample.Migrations/EFCores/ShardingSqlServerMigrationsSqlGenerator.cs @@ -0,0 +1,33 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations.Operations; +using ShardingCore.Helpers; +using ShardingCore.Sharding.Abstractions; + +namespace Sample.Migrations.EFCores +{ + /// + /// https://github.com/Coldairarrow/EFCore.Sharding/blob/master/src/EFCore.Sharding.SqlServer/ShardingSqlServerMigrationsSqlGenerator.cs + /// + public class ShardingSqlServerMigrationsSqlGenerator : SqlServerMigrationsSqlGenerator where TShardingDbContext:DbContext,IShardingDbContext + { + public ShardingSqlServerMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, IRelationalAnnotationProvider migrationsAnnotations) : base(dependencies, migrationsAnnotations) + { + } + protected override void Generate( + MigrationOperation operation, + IModel model, + MigrationCommandListBuilder builder) + { + var oldCmds = builder.GetCommandList().ToList(); + base.Generate(operation, model, builder); + var newCmds = builder.GetCommandList().ToList(); + var addCmds = newCmds.Where(x => !oldCmds.Contains(x)).ToList(); + + MigrationHelper.Generate(operation, builder, Dependencies.SqlGenerationHelper, addCmds); + } + } +} diff --git a/samples/Sample.Migrations/EFCores/ShardingWithDateTime.cs b/samples/Sample.Migrations/EFCores/ShardingWithDateTime.cs new file mode 100644 index 00000000..818e5112 --- /dev/null +++ b/samples/Sample.Migrations/EFCores/ShardingWithDateTime.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Core; +using ShardingCore.VirtualRoutes.Months; + +namespace Sample.Migrations.EFCores +{ + public class ShardingWithDateTime:IShardingTable + { + public string Id { get; set; } + public string Name { get; set; } + public int Age { get; set; } + [ShardingTableKey] + public DateTime CreateTime { get; set; } + } + + public class ShardingWithDateTimeMap : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(128); + builder.Property(o => o.Name).HasMaxLength(128); + builder.ToTable(nameof(ShardingWithDateTime)); + } + } + public class ShardingWithDateTimeVirtualTableRoute : AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute + { + public override DateTime GetBeginTime() + { + return new DateTime(2021, 9, 1); + } + } +} diff --git a/samples/Sample.Migrations/EFCores/ShardingWithMod.cs b/samples/Sample.Migrations/EFCores/ShardingWithMod.cs new file mode 100644 index 00000000..bd2bc9b3 --- /dev/null +++ b/samples/Sample.Migrations/EFCores/ShardingWithMod.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Core; +using ShardingCore.VirtualRoutes.Mods; +using ShardingCore.VirtualRoutes.Months; + +namespace Sample.Migrations.EFCores +{ + public class ShardingWithMod:IShardingTable + { + [ShardingTableKey] + public string Id { get; set; } + public string Name { get; set; } + public int Age { get; set; } + } + + public class ShardingWithModMap : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(128); + builder.Property(o => o.Name).HasMaxLength(128); + builder.ToTable(nameof(ShardingWithMod)); + } + } + public class ShardingWithModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute + { + public ShardingWithModVirtualTableRoute() : base(2, 3) + { + } + } +} diff --git a/samples/Sample.Migrations/Migrations/ShardingMigrations/20211006202136_EFCoreSharding.Designer.cs b/samples/Sample.Migrations/Migrations/ShardingMigrations/20211006202136_EFCoreSharding.Designer.cs new file mode 100644 index 00000000..22175940 --- /dev/null +++ b/samples/Sample.Migrations/Migrations/ShardingMigrations/20211006202136_EFCoreSharding.Designer.cs @@ -0,0 +1,86 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sample.Migrations.EFCores; + +namespace Sample.Migrations.Migrations.ShardingMigrations +{ + [DbContext(typeof(DefaultShardingTableDbContext))] + [Migration("20211006202136_EFCoreSharding")] + partial class EFCoreSharding + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.10") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Sample.Migrations.EFCores.NoShardingTable", b => + { + b.Property("Id") + .HasMaxLength(128) + .IsUnicode(false) + .HasColumnType("varchar(128)"); + + b.Property("Age") + .HasColumnType("int"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.ToTable("NoShardingTable"); + }); + + modelBuilder.Entity("Sample.Migrations.EFCores.ShardingWithDateTime", b => + { + b.Property("Id") + .HasMaxLength(128) + .IsUnicode(false) + .HasColumnType("varchar(128)"); + + b.Property("Age") + .HasColumnType("int"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.ToTable("ShardingWithDateTime"); + }); + + modelBuilder.Entity("Sample.Migrations.EFCores.ShardingWithMod", b => + { + b.Property("Id") + .HasMaxLength(128) + .IsUnicode(false) + .HasColumnType("varchar(128)"); + + b.Property("Age") + .HasColumnType("int"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.ToTable("ShardingWithMod"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/samples/Sample.Migrations/Migrations/ShardingMigrations/20211006202136_EFCoreSharding.cs b/samples/Sample.Migrations/Migrations/ShardingMigrations/20211006202136_EFCoreSharding.cs new file mode 100644 index 00000000..ed7bf63f --- /dev/null +++ b/samples/Sample.Migrations/Migrations/ShardingMigrations/20211006202136_EFCoreSharding.cs @@ -0,0 +1,63 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sample.Migrations.Migrations.ShardingMigrations +{ + public partial class EFCoreSharding : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "NoShardingTable", + columns: table => new + { + Id = table.Column(type: "varchar(128)", unicode: false, maxLength: 128, nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + Age = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_NoShardingTable", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ShardingWithDateTime", + columns: table => new + { + Id = table.Column(type: "varchar(128)", unicode: false, maxLength: 128, nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + Age = table.Column(type: "int", nullable: false), + CreateTime = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ShardingWithDateTime", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ShardingWithMod", + columns: table => new + { + Id = table.Column(type: "varchar(128)", unicode: false, maxLength: 128, nullable: false), + Name = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + Age = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ShardingWithMod", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "NoShardingTable"); + + migrationBuilder.DropTable( + name: "ShardingWithDateTime"); + + migrationBuilder.DropTable( + name: "ShardingWithMod"); + } + } +} diff --git a/samples/Sample.Migrations/Migrations/ShardingMigrations/DefaultShardingTableDbContextModelSnapshot.cs b/samples/Sample.Migrations/Migrations/ShardingMigrations/DefaultShardingTableDbContextModelSnapshot.cs new file mode 100644 index 00000000..c2a47a3e --- /dev/null +++ b/samples/Sample.Migrations/Migrations/ShardingMigrations/DefaultShardingTableDbContextModelSnapshot.cs @@ -0,0 +1,84 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sample.Migrations.EFCores; + +namespace Sample.Migrations.Migrations.ShardingMigrations +{ + [DbContext(typeof(DefaultShardingTableDbContext))] + partial class DefaultShardingTableDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.10") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Sample.Migrations.EFCores.NoShardingTable", b => + { + b.Property("Id") + .HasMaxLength(128) + .IsUnicode(false) + .HasColumnType("varchar(128)"); + + b.Property("Age") + .HasColumnType("int"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.ToTable("NoShardingTable"); + }); + + modelBuilder.Entity("Sample.Migrations.EFCores.ShardingWithDateTime", b => + { + b.Property("Id") + .HasMaxLength(128) + .IsUnicode(false) + .HasColumnType("varchar(128)"); + + b.Property("Age") + .HasColumnType("int"); + + b.Property("CreateTime") + .HasColumnType("datetime2"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.ToTable("ShardingWithDateTime"); + }); + + modelBuilder.Entity("Sample.Migrations.EFCores.ShardingWithMod", b => + { + b.Property("Id") + .HasMaxLength(128) + .IsUnicode(false) + .HasColumnType("varchar(128)"); + + b.Property("Age") + .HasColumnType("int"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.ToTable("ShardingWithMod"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/samples/Sample.Migrations/Program.cs b/samples/Sample.Migrations/Program.cs new file mode 100644 index 00000000..d9b8975b --- /dev/null +++ b/samples/Sample.Migrations/Program.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Sample.Migrations +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/samples/Sample.Migrations/Properties/launchSettings.json b/samples/Sample.Migrations/Properties/launchSettings.json new file mode 100644 index 00000000..e659e655 --- /dev/null +++ b/samples/Sample.Migrations/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:7924", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "weatherforecast", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Sample.Migrations": { + "commandName": "Project", + "dotnetRunMessages": "true", + "launchBrowser": true, + "launchUrl": "weatherforecast", + "applicationUrl": "http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/samples/Sample.Migrations/Sample.Migrations.csproj b/samples/Sample.Migrations/Sample.Migrations.csproj new file mode 100644 index 00000000..94cbee39 --- /dev/null +++ b/samples/Sample.Migrations/Sample.Migrations.csproj @@ -0,0 +1,19 @@ + + + + net5.0 + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/samples/Sample.Migrations/Startup.cs b/samples/Sample.Migrations/Startup.cs new file mode 100644 index 00000000..83e3fde3 --- /dev/null +++ b/samples/Sample.Migrations/Startup.cs @@ -0,0 +1,78 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Migrations; +using Sample.Migrations.EFCores; +using ShardingCore; + +namespace Sample.Migrations +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + + services.AddControllers(); + + services.AddShardingDbContext( + o => + o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBMigration;Integrated Security=True;") + .ReplaceService>() + ).Begin(o => + { + o.CreateShardingTableOnStart = false; + o.EnsureCreatedWithOutShardingTable = false; + o.AutoTrackEntity = true; + }) + .AddShardingQuery((conStr, builder) => builder.UseSqlServer(conStr) + .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)) + .AddShardingTransaction((connection, builder) => + builder.UseSqlServer(connection)) + .AddDefaultDataSource("ds0", + "Data Source=localhost;Initial Catalog=ShardingCoreDBMigration;Integrated Security=True;") + .AddShardingTableRoute(o => + { + o.AddShardingTableRoute(); + o.AddShardingTableRoute(); + }).End(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + var shardingBootstrapper = app.ApplicationServices.GetRequiredService(); + shardingBootstrapper.Start(); + + app.UseRouting(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + } +} diff --git a/samples/Sample.Migrations/WeatherForecast.cs b/samples/Sample.Migrations/WeatherForecast.cs new file mode 100644 index 00000000..5c77902d --- /dev/null +++ b/samples/Sample.Migrations/WeatherForecast.cs @@ -0,0 +1,15 @@ +using System; + +namespace Sample.Migrations +{ + public class WeatherForecast + { + public DateTime Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string Summary { get; set; } + } +} diff --git a/samples/Sample.Migrations/appsettings.Development.json b/samples/Sample.Migrations/appsettings.Development.json new file mode 100644 index 00000000..8983e0fc --- /dev/null +++ b/samples/Sample.Migrations/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/samples/Sample.Migrations/appsettings.json b/samples/Sample.Migrations/appsettings.json new file mode 100644 index 00000000..d9d9a9bf --- /dev/null +++ b/samples/Sample.Migrations/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/samples/Sample.MySql/Controllers/WeatherForecastController.cs b/samples/Sample.MySql/Controllers/WeatherForecastController.cs index 620b4c2f..bd9dae5b 100644 --- a/samples/Sample.MySql/Controllers/WeatherForecastController.cs +++ b/samples/Sample.MySql/Controllers/WeatherForecastController.cs @@ -34,7 +34,7 @@ // [HttpGet] // public async Task Get() // { -// var taleAllTails = _virtualTableManager.GetVirtualTable(typeof(SysUserLogByMonth)).GetTaleAllTails(); +// var taleAllTails = _virtualTableManager.GetVirtualTable(typeof(SysUserLogByMonth)).GetTableAllTails(); // // // var result = await _defaultTableDbContext.Set().AnyAsync(); diff --git a/samples/Sample.SqlServer/Startup.cs b/samples/Sample.SqlServer/Startup.cs index de75064d..5d1b53e0 100644 --- a/samples/Sample.SqlServer/Startup.cs +++ b/samples/Sample.SqlServer/Startup.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Concurrent; using System.Collections.Generic; using Microsoft.AspNetCore.Builder; @@ -38,6 +39,8 @@ namespace Sample.SqlServer o.CreateShardingTableOnStart = true; o.EnsureCreatedWithOutShardingTable = true; o.AutoTrackEntity = true; + o.ParallelQueryMaxThreadCount = 100; + o.ParallelQueryTimeOut=TimeSpan.FromSeconds(10); }) .AddShardingQuery((conStr, builder) => builder.UseSqlServer(conStr).UseLoggerFactory(efLogger) .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)) diff --git a/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/VirtualDataSource.cs b/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/VirtualDataSource.cs index 96d8f48a..10120fd1 100644 --- a/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/VirtualDataSource.cs +++ b/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/VirtualDataSource.cs @@ -34,7 +34,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources public List RouteTo(Type entityType,ShardingDataSourceRouteConfig routeRouteConfig) { - var shardingEntityConfig = ShardingUtil.Parse(entityType); var virtualDataSourceRoute = GetRoute( entityType); if (routeRouteConfig.UseQueryable()) @@ -46,7 +45,10 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources shardingKeyValue = routeRouteConfig.GetShardingKeyValue(); if (routeRouteConfig.UseEntity()) + { + var shardingEntityConfig = ShardingUtil.Parse(entityType); shardingKeyValue = routeRouteConfig.GetShardingDataSource().GetPropertyValue(shardingEntityConfig.ShardingDataSourceField); + } if (shardingKeyValue != null) { diff --git a/src/ShardingCore/Core/VirtualDatabase/VirtualTables/DefaultVirtualTable.cs b/src/ShardingCore/Core/VirtualDatabase/VirtualTables/DefaultVirtualTable.cs index e65a20a2..1b51dc3b 100644 --- a/src/ShardingCore/Core/VirtualDatabase/VirtualTables/DefaultVirtualTable.cs +++ b/src/ShardingCore/Core/VirtualDatabase/VirtualTables/DefaultVirtualTable.cs @@ -111,7 +111,7 @@ namespace ShardingCore.Core.VirtualTables return GetVirtualRoute(); } - public List GetTaleAllTails() + public List GetTableAllTails() { return _physicTables.Keys.Select(o => o.Tail).ToList(); } diff --git a/src/ShardingCore/Core/VirtualDatabase/VirtualTables/IVirtualTable.cs b/src/ShardingCore/Core/VirtualDatabase/VirtualTables/IVirtualTable.cs index 790b59e5..26d60dc6 100644 --- a/src/ShardingCore/Core/VirtualDatabase/VirtualTables/IVirtualTable.cs +++ b/src/ShardingCore/Core/VirtualDatabase/VirtualTables/IVirtualTable.cs @@ -77,7 +77,7 @@ namespace ShardingCore.Core.VirtualTables /// CreateDateTables /// /// - List GetTaleAllTails(); + List GetTableAllTails(); } public interface IVirtualTable : IVirtualTable where T : class,IShardingTable diff --git a/src/ShardingCore/EFCores/ShardingModelCustomizer.cs b/src/ShardingCore/EFCores/ShardingModelCustomizer.cs index 8544e78d..e423c342 100644 --- a/src/ShardingCore/EFCores/ShardingModelCustomizer.cs +++ b/src/ShardingCore/EFCores/ShardingModelCustomizer.cs @@ -41,7 +41,7 @@ namespace ShardingCore.EFCores var singleQueryRouteTail = (ISingleQueryRouteTail) shardingTableDbContext.RouteTail; var tail = singleQueryRouteTail.GetTail(); var virtualTableManager = ShardingContainer.GetService>(); - var typeMap = virtualTableManager.GetAllVirtualTables().Where(o => o.GetTaleAllTails().Contains(tail)).Select(o => o.EntityType).ToHashSet(); + var typeMap = virtualTableManager.GetAllVirtualTables().Where(o => o.GetTableAllTails().Contains(tail)).Select(o => o.EntityType).ToHashSet(); //设置分表 var mutableEntityTypes = modelBuilder.Model.GetEntityTypes().Where(o => o.ClrType.IsShardingTable() && typeMap.Contains(o.ClrType)); diff --git a/src/ShardingCore/Extensions/DbContextExtension.cs b/src/ShardingCore/Extensions/DbContextExtension.cs index be17f967..b9c03e26 100644 --- a/src/ShardingCore/Extensions/DbContextExtension.cs +++ b/src/ShardingCore/Extensions/DbContextExtension.cs @@ -162,16 +162,9 @@ namespace ShardingCore.Extensions var primaryKeyValue = ShardingKeyUtil.GetPrimaryKeyValues(entity); if (primaryKeyValue.IsEmpty()) return null; - var entry = context.ChangeTracker.Entries().FirstOrDefault(e => primaryKeyValue.SequenceEqual(ShardingKeyUtil.GetPrimaryKeyValues(e.Entity))); - if (entry != null) - { - if (entry.State != EntityState.Detached) - { - return entry.Entity; - } - } + var entry = context.ChangeTracker.Entries().FirstOrDefault(e =>e.State != EntityState.Detached&&primaryKeyValue.SequenceEqual(ShardingKeyUtil.GetPrimaryKeyValues(e.Entity))); - return null; + return entry?.Entity; } } diff --git a/src/ShardingCore/Helpers/MigrationHelper.cs b/src/ShardingCore/Helpers/MigrationHelper.cs new file mode 100644 index 00000000..e333d64c --- /dev/null +++ b/src/ShardingCore/Helpers/MigrationHelper.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations.Operations; +using Microsoft.EntityFrameworkCore.Storage; +using ShardingCore.Core.VirtualDatabase.VirtualTables; +using ShardingCore.Extensions; +using ShardingCore.Sharding.Abstractions; + +namespace ShardingCore.Helpers +{ + /* + * @Author: xjm + * @Description: + * @Date: 2021/10/6 8:11:59 + * @Ver: 1.0 + * @Email: 326308290@qq.com + */ + /// + /// https://github.com/Coldairarrow/EFCore.Sharding/blob/master/src/EFCore.Sharding/Migrations/MigrationHelper.cs + /// + public class MigrationHelper + { + private MigrationHelper() { } + public static void Generate( + MigrationOperation operation, + MigrationCommandListBuilder builder, + ISqlGenerationHelper sqlGenerationHelper, + List addCmds + ) where TShardingDContext:DbContext,IShardingDbContext + { + + addCmds.ForEach(aAddCmd => + { + var shardingCmds = BuildShardingCmds(operation, aAddCmd.CommandText, sqlGenerationHelper); + //针对builder的原始表进行移除 + shardingCmds.ForEach(aShardingCmd => + { + builder.Append(aShardingCmd) + .EndCommand(); + }); + }); + } + + private static List BuildShardingCmds(MigrationOperation operation, string sourceCmd, ISqlGenerationHelper sqlGenerationHelper) + where TShardingDContext : DbContext, IShardingDbContext + { + //所有MigrationOperation定义 + //https://github.com/dotnet/efcore/tree/b970bf29a46521f40862a01db9e276e6448d3cb0/src/EFCore.Relational/Migrations/Operations + //ColumnOperation仅替换Table + //其余其余都是将Name和Table使用分表名替换 + var virtualTableManager = ShardingContainer.GetService>(); + var allVirtualTables = virtualTableManager.GetAllVirtualTables(); + var existsShardingTables = allVirtualTables.ToDictionary(o => o.ShardingConfig.VirtualTableName, o => o.GetAllPhysicTables().Select(p=>p.FullName).ToList()); + //Dictionary> _existsShardingTables + // = Cache.ServiceProvider.GetService().ExistsShardingTables; + List resList = new List(); + string absTableName = string.Empty; + + string name = operation.GetPropertyValue("Name") as string; + string tableName = operation.GetPropertyValue("Table") as string; + string pattern = string.Format("^({0})$|^({0}_.*?)$|^(.*?_{0}_.*?)$|^(.*?_{0})$", absTableName); + Func>, bool> where = x => + existsShardingTables.Any(y =>x.Key==y.Key&& Regex.IsMatch(name, BuildPattern(y.Key))); + + if (!string.IsNullOrWhiteSpace(tableName)) + { + absTableName = tableName; + } + else if (!string.IsNullOrWhiteSpace(name) && existsShardingTables.Any(x => where(x))) + { + absTableName = existsShardingTables.Where(x => where(x)).FirstOrDefault().Key; + } + + //分表 + if (!string.IsNullOrWhiteSpace(absTableName) && existsShardingTables.ContainsKey(absTableName)) + { + var shardings = existsShardingTables[absTableName]; + shardings.ForEach(aShardingTable => + { + string newCmd = sourceCmd; + GetReplaceGroups(operation, absTableName, aShardingTable).ForEach(aReplace => + { + newCmd = newCmd.Replace( + sqlGenerationHelper.DelimitIdentifier(aReplace.sourceName), + sqlGenerationHelper.DelimitIdentifier(aReplace.targetName)); + }); + resList.Add(newCmd); + }); + } + + return resList; + + string BuildPattern(string absTableName) + { + return string.Format("^({0})$|^({0}_.*?)$|^(.*?_{0}_.*?)$|^(.*?_{0})$", absTableName); + } + } + private static List<(string sourceName, string targetName)> GetReplaceGroups( + MigrationOperation operation, string sourceTableName, string targetTableName) + { + List<(string sourceName, string targetName)> resList = + new List<(string sourceName, string targetName)> + { + (sourceTableName, targetTableName) + }; + + string name = operation.GetPropertyValue("Name") as string; + if (!string.IsNullOrWhiteSpace(name) && !(operation is ColumnOperation)) + { + string[] patterns = new string[] { $"^()({sourceTableName})()$", $"^()({sourceTableName})(_.*?)$", $"^(.*?_)({sourceTableName})(_.*?)$", $"^(.*?_)({sourceTableName})()$" }; + foreach (var aPattern in patterns) + { + if (Regex.IsMatch(name, aPattern)) + { + var newName = new Regex(aPattern).Replace(name, "${1}" + targetTableName + "$3"); + resList.Add((name, newName)); + break; + } + } + } + Func listPropertyWhere = x => + x.PropertyType.IsGenericType + && x.PropertyType.GetGenericTypeDefinition() == typeof(List<>) + && typeof(MigrationOperation).IsAssignableFrom(x.PropertyType.GetGenericArguments()[0]); + //其它 + operation.GetType().GetProperties() + .Where(x => x.Name != "Name" + && x.Name != "Table" + && x.PropertyType != typeof(object) + && (typeof(MigrationOperation).IsAssignableFrom(x.PropertyType) || listPropertyWhere(x)) + ) + .ToList() + .ForEach(aProperty => + { + var propertyValue = aProperty.GetValue(operation); + if (propertyValue is MigrationOperation propertyOperation) + { + resList.AddRange(GetReplaceGroups(propertyOperation, sourceTableName, targetTableName)); + } + else if (listPropertyWhere(aProperty)) + { + foreach (var aValue in (IEnumerable)propertyValue) + { + resList.AddRange(GetReplaceGroups((MigrationOperation)aValue, sourceTableName, targetTableName)); + } + } + }); + + return resList; + } + } +} diff --git a/src/ShardingCore/Sharding/ShardingDbContextExecutors/ShardingDbContextExecutor.cs b/src/ShardingCore/Sharding/ShardingDbContextExecutors/ShardingDbContextExecutor.cs index 27e4e72c..e7f51fd3 100644 --- a/src/ShardingCore/Sharding/ShardingDbContextExecutors/ShardingDbContextExecutor.cs +++ b/src/ShardingCore/Sharding/ShardingDbContextExecutors/ShardingDbContextExecutor.cs @@ -34,7 +34,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors private readonly ConcurrentDictionary> _dbContextCaches = new ConcurrentDictionary>(); public IShardingTransaction CurrentShardingTransaction { get; private set; } private readonly IVirtualDataSource _virtualDataSource; - private readonly IVirtualTableManager _virtualTableManager; + private readonly IVirtualTableManager _virtualTableManager; private readonly IShardingDbContextFactory _shardingDbContextFactory; private readonly IShardingDbContextOptionsBuilderConfig _shardingDbContextOptionsBuilderConfig; private readonly IRouteTailFactory _routeTailFactory; diff --git a/src/ShardingCore/ShardingBootstrapper.cs b/src/ShardingCore/ShardingBootstrapper.cs index e2101ba8..b750805e 100644 --- a/src/ShardingCore/ShardingBootstrapper.cs +++ b/src/ShardingCore/ShardingBootstrapper.cs @@ -14,10 +14,10 @@ namespace ShardingCore { private readonly IEnumerable _shardingConfigOptions; - public ShardingBootstrapper(IServiceProvider serviceProvider, IEnumerable shardingConfigOptions) + public ShardingBootstrapper(IServiceProvider serviceProvider) { ShardingContainer.SetServices(serviceProvider); - _shardingConfigOptions = shardingConfigOptions; + _shardingConfigOptions = ShardingContainer.GetServices(); } public void Start() diff --git a/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute.cs index e9e37f28..83ef27de 100644 --- a/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute.cs @@ -26,11 +26,11 @@ namespace ShardingCore.VirtualRoutes.Days /// public override List GetAllTails() { - var beginTime = GetBeginTime(); + var beginTime = GetBeginTime().Date; var tails=new List(); //提前创建表 - var nowTimeStamp = DateTime.Now.AddDays(1).Date; + var nowTimeStamp = DateTime.Now.Date; if (beginTime > nowTimeStamp) throw new ArgumentException("begin time error"); var currentTimeStamp = beginTime; diff --git a/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyLongVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyLongVirtualTableRoute.cs index d8295875..748c404c 100644 --- a/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyLongVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyLongVirtualTableRoute.cs @@ -20,11 +20,11 @@ namespace ShardingCore.VirtualRoutes.Days public abstract DateTime GetBeginTime(); public override List GetAllTails() { - var beginTime = GetBeginTime(); + var beginTime = GetBeginTime().Date; var tails=new List(); //提前创建表 - var nowTimeStamp = DateTime.Now.AddDays(1).Date; + var nowTimeStamp = DateTime.Now.Date; if (beginTime > nowTimeStamp) throw new ArgumentException("begin time error"); var currentTimeStamp = beginTime; diff --git a/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute.cs index d6bd1eb8..66f7d46d 100644 --- a/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute.cs @@ -23,7 +23,7 @@ namespace ShardingCore.VirtualRoutes.Months var tails=new List(); //提前创建表 - var nowTimeStamp =ShardingCoreHelper.GetNextMonthFirstDay(DateTime.Now); + var nowTimeStamp =ShardingCoreHelper.GetCurrentMonthFirstDay(DateTime.Now); if (beginTime > nowTimeStamp) throw new ArgumentException("begin time error"); var currentTimeStamp = beginTime; diff --git a/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyLongVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyLongVirtualTableRoute.cs index 7e8db45f..e9ae0736 100644 --- a/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyLongVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyLongVirtualTableRoute.cs @@ -23,7 +23,7 @@ namespace ShardingCore.VirtualRoutes.Months var tails=new List(); //提前创建表 - var nowTimeStamp =ShardingCoreHelper.GetNextMonthFirstDay(DateTime.Now); + var nowTimeStamp =ShardingCoreHelper.GetCurrentMonthFirstDay(DateTime.Now); if (beginTime > nowTimeStamp) throw new ArgumentException("begin time error"); var currentTimeStamp = beginTime; diff --git a/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute.cs index fa46bbfe..73d09de6 100644 --- a/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute.cs @@ -19,11 +19,11 @@ namespace ShardingCore.VirtualRoutes.Weeks public abstract DateTime GetBeginTime(); public override List GetAllTails() { - var beginTime = GetBeginTime(); + var beginTime = GetBeginTime().Date; var tails=new List(); //提前创建表 - var nowTimeStamp = DateTime.Now.AddDays(7).Date; + var nowTimeStamp = DateTime.Now.Date; if (beginTime > nowTimeStamp) throw new ArgumentException("begin time error"); var currentTimeStamp = beginTime; diff --git a/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyLongVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyLongVirtualTableRoute.cs index 35381fdc..da30f0c2 100644 --- a/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyLongVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyLongVirtualTableRoute.cs @@ -19,11 +19,11 @@ namespace ShardingCore.VirtualRoutes.Weeks public abstract DateTime GetBeginTime(); public override List GetAllTails() { - var beginTime = GetBeginTime(); + var beginTime = GetBeginTime().Date; var tails=new List(); //提前创建表 - var nowTimeStamp = DateTime.Now.AddDays(7).Date; + var nowTimeStamp = DateTime.Now.Date; if (beginTime > nowTimeStamp) throw new ArgumentException("begin time error"); var currentTimeStamp = beginTime; diff --git a/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute.cs index 99f351ca..b2065135 100644 --- a/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute.cs @@ -18,11 +18,11 @@ namespace ShardingCore.VirtualRoutes.Years public abstract DateTime GetBeginTime(); public override List GetAllTails() { - var beginTime = GetBeginTime(); + var beginTime = GetBeginTime().Date; var tails=new List(); //提前创建表 - var nowTimeStamp = DateTime.Now.AddYears(1).Date; + var nowTimeStamp = DateTime.Now.Date; if (beginTime > nowTimeStamp) throw new ArgumentException("begin time error"); var currentTimeStamp = beginTime; diff --git a/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyLongVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyLongVirtualTableRoute.cs index dadff271..0fbde5cb 100644 --- a/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyLongVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyLongVirtualTableRoute.cs @@ -19,11 +19,11 @@ namespace ShardingCore.VirtualRoutes.Years public abstract DateTime GetBeginTime(); public override List GetAllTails() { - var beginTime = GetBeginTime(); + var beginTime = GetBeginTime().Date; var tails=new List(); //提前创建表 - var nowTimeStamp = DateTime.Now.AddYears(1).Date; + var nowTimeStamp = DateTime.Now.Date; if (beginTime > nowTimeStamp) throw new ArgumentException("begin time error"); var currentTimeStamp = beginTime;