Skip to content

Commit

Permalink
分表 数据库迁移
Browse files Browse the repository at this point in the history
  • Loading branch information
Coldairarrow committed Sep 26, 2020
1 parent 3e84506 commit d16ff66
Show file tree
Hide file tree
Showing 15 changed files with 348 additions and 33 deletions.
28 changes: 13 additions & 15 deletions examples/Demo.DbMigrator/DesignTimeDbContextFactory.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,33 @@
using EFCore.Sharding;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;

namespace DbMigrator
{
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<CustomContext>, IDesignTimeServices
public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<CustomContext>
{
public void ConfigureDesignTimeServices(IServiceCollection serviceCollection)
static DesignTimeDbContextFactory()
{
throw new System.NotImplementedException();
ServiceCollection services = new ServiceCollection();
services.AddEFCoreSharding(x =>
{
x.MigrationsWithoutForeignKey();
});
ServiceProvider = services.BuildServiceProvider();
new EFCoreShardingBootstrapper(ServiceProvider).StartAsync(default).Wait();
}

public static readonly IServiceProvider ServiceProvider;

/// <summary>
/// 创建数据库上下文
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public CustomContext CreateDbContext(string[] args)
{
using var host = Host.CreateDefaultBuilder()
.ConfigureServices(services =>
{
services.AddEFCoreSharding(x =>
{
x.MigrationsWithoutForeignKey();
});
}).Build();
host.Start();

var db = host.Services
var db = ServiceProvider
.GetService<IDbFactory>()
.GetDbContext(new DbContextParamters
{
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Demo.DbMigrator.Migrations
{
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Order",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
DateTime = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Order", x => x.Id);
});

migrationBuilder.CreateTable(
name: "OrderItem",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
OrderId = table.Column<Guid>(nullable: false),
Name = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_OrderItem", x => x.Id);
});

migrationBuilder.CreateIndex(
name: "IX_OrderItem_OrderId",
table: "OrderItem",
column: "OrderId");
}

protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "OrderItem");

migrationBuilder.DropTable(
name: "Order");
}
}
}
66 changes: 66 additions & 0 deletions examples/Demo.DbMigrator/Migrations/CustomContextModelSnapshot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// <auto-generated />
using System;
using DbMigrator;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

namespace Demo.DbMigrator.Migrations
{
[DbContext(typeof(CustomContext))]
partial class CustomContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.8")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

modelBuilder.Entity("Demo.DbMigrator.Order", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");

b.Property<DateTime>("DateTime")
.HasColumnType("datetime2");

b.HasKey("Id");

b.ToTable("Order");
});

modelBuilder.Entity("Demo.DbMigrator.OrderItem", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");

b.Property<string>("Name")
.HasColumnType("nvarchar(max)");

b.Property<Guid>("OrderId")
.HasColumnType("uniqueidentifier");

b.HasKey("Id");

b.HasIndex("OrderId");

b.ToTable("OrderItem");
});

modelBuilder.Entity("Demo.DbMigrator.OrderItem", b =>
{
b.HasOne("Demo.DbMigrator.Order", null)
.WithMany("OrderItems")
.HasForeignKey("OrderId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}
1 change: 1 addition & 0 deletions examples/Demo.DbMigrator/a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Name":"Order","Schema":null,"PrimaryKey":{"Schema":null,"Table":"Order","Name":"PK_Order","Columns":["Id"],"IsDestructiveChange":false},"Columns":[{"Name":"Id","Schema":null,"Table":"Order","ClrType":"System.Guid, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","ColumnType":null,"IsUnicode":null,"IsFixedLength":false,"MaxLength":null,"IsRowVersion":false,"IsNullable":false,"DefaultValue":null,"DefaultValueSql":null,"ComputedColumnSql":null,"Comment":null,"IsDestructiveChange":false},{"Name":"DateTime","Schema":null,"Table":"Order","ClrType":"System.DateTime, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","ColumnType":null,"IsUnicode":null,"IsFixedLength":false,"MaxLength":null,"IsRowVersion":false,"IsNullable":false,"DefaultValue":null,"DefaultValueSql":null,"ComputedColumnSql":null,"Comment":null,"IsDestructiveChange":false}],"ForeignKeys":[],"UniqueConstraints":[],"CheckConstraints":[],"Comment":null,"IsDestructiveChange":false}{"Name":"OrderItem","Schema":null,"PrimaryKey":{"Schema":null,"Table":"OrderItem","Name":"PK_OrderItem","Columns":["Id"],"IsDestructiveChange":false},"Columns":[{"Name":"Id","Schema":null,"Table":"OrderItem","ClrType":"System.Guid, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","ColumnType":null,"IsUnicode":null,"IsFixedLength":false,"MaxLength":null,"IsRowVersion":false,"IsNullable":false,"DefaultValue":null,"DefaultValueSql":null,"ComputedColumnSql":null,"Comment":null,"IsDestructiveChange":false},{"Name":"OrderId","Schema":null,"Table":"OrderItem","ClrType":"System.Guid, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","ColumnType":null,"IsUnicode":null,"IsFixedLength":false,"MaxLength":null,"IsRowVersion":false,"IsNullable":false,"DefaultValue":null,"DefaultValueSql":null,"ComputedColumnSql":null,"Comment":null,"IsDestructiveChange":false},{"Name":"Name","Schema":null,"Table":"OrderItem","ClrType":"System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e","ColumnType":null,"IsUnicode":null,"IsFixedLength":false,"MaxLength":null,"IsRowVersion":false,"IsNullable":true,"DefaultValue":null,"DefaultValueSql":null,"ComputedColumnSql":null,"Comment":null,"IsDestructiveChange":false}],"ForeignKeys":[],"UniqueConstraints":[],"CheckConstraints":[],"Comment":null,"IsDestructiveChange":false}
5 changes: 1 addition & 4 deletions src/EFCore.Sharding/DbFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,7 @@ public GenericDbContext GetDbContext(DbContextParamters options)
provider.UseDatabase(builder, dbConnection);
builder.ReplaceService<IModelCacheKeyFactory, GenericModelCacheKeyFactory>();
#if EFCORE3
if (_shardingOptions.MigrationsWithoutForeignKey)
{
builder.ReplaceService<IMigrationsModelDiffer, MigrationsWithoutForeignKey>();
}
builder.ReplaceService<IMigrationsModelDiffer, ShardingMigration>();
#endif
return new GenericDbContext(builder.Options, options, _shardingOptions);
}
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using EFCore.Sharding.Config;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using System;
Expand All @@ -7,14 +8,15 @@

namespace EFCore.Sharding
{
internal class Bootstrapper : BackgroundService
public class EFCoreShardingBootstrapper : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
private readonly EFCoreShardingOptions _shardingOptions;
public Bootstrapper(IServiceProvider serviceProvider, IOptions<EFCoreShardingOptions> shardingOptions)
public EFCoreShardingBootstrapper(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_shardingOptions = shardingOptions.Value;
_shardingOptions = serviceProvider.GetService<IOptions<EFCoreShardingOptions>>().Value;

Cache.ServiceProvider = serviceProvider;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static IServiceCollection AddEFCoreSharding(this IServiceCollection servi
services.AddSingleton<IDbFactory, DbFactory>();
services.AddScoped<IShardingDbAccessor, ShardingDbAccessor>();

services.AddHostedService<Bootstrapper>();
services.AddHostedService<EFCoreShardingBootstrapper>();

return services;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#if EFCORE3
using EFCore.Sharding.Config;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
Expand All @@ -7,16 +8,20 @@
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Update;
using Microsoft.EntityFrameworkCore.Update.Internal;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;

namespace EFCore.Sharding
{
[SuppressMessage("Usage", "EF1001:Internal EF Core API usage.", Justification = "<挂起>")]
internal class MigrationsWithoutForeignKey : MigrationsModelDiffer
internal class ShardingMigration : MigrationsModelDiffer
{
public MigrationsWithoutForeignKey(
public ShardingMigration(
IRelationalTypeMappingSource typeMappingSource,
IMigrationsAnnotationProvider migrationsAnnotations,
IChangeDetector changeDetector,
Expand All @@ -25,22 +30,30 @@ CommandBatchPreparerDependencies commandBatchPreparerDependencies
)
: base(typeMappingSource, migrationsAnnotations, changeDetector, updateAdapterFactory, commandBatchPreparerDependencies)
{
//_dbFactory = dbFactory;
}

public override IReadOnlyList<MigrationOperation> GetDifferences(IModel source, IModel target)
{
var operations = base.GetDifferences(source, target)
.Where(op => !(op is AddForeignKeyOperation))
.Where(op => !(op is DropForeignKeyOperation))
.ToList();
List<MigrationOperation> resList = new List<MigrationOperation>();

foreach (var operation in operations.OfType<CreateTableOperation>())
var shardingOption = Cache.ServiceProvider.GetService<IOptions<EFCoreShardingOptions>>().Value;
var sourceOperations = base.GetDifferences(source, target).ToList();

//忽略外键
if (shardingOption.MigrationsWithoutForeignKey)
{
operation.ForeignKeys?.Clear();
sourceOperations.RemoveAll(x => x is AddForeignKeyOperation || x is DropForeignKeyOperation);
foreach (var operation in sourceOperations.OfType<CreateTableOperation>())
{
operation.ForeignKeys?.Clear();
}
}
resList.AddRange(sourceOperations);

//分表


return operations;
return resList;
}
}
}
Expand Down
Loading

0 comments on commit d16ff66

Please sign in to comment.