Skip to content

Commit a04ca15

Browse files
committed
优化添加脚本分片的支持并且发布x.6.0.34
1 parent 071a9c9 commit a04ca15

9 files changed

+213
-112
lines changed

nuget-publish.bat

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
:start
22
::定义版本
3-
set EFCORE2=2.6.0.33
4-
set EFCORE3=3.6.0.33
5-
set EFCORE5=5.6.0.33
6-
set EFCORE6=6.6.0.33
3+
set EFCORE2=2.6.0.34
4+
set EFCORE3=3.6.0.34
5+
set EFCORE5=5.6.0.34
6+
set EFCORE6=6.6.0.34
77

88
::删除所有bin与obj下的文件
99
@echo off
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Microsoft.EntityFrameworkCore.Infrastructure;
7+
using Microsoft.EntityFrameworkCore.Migrations;
8+
using ShardingCore.Core.DbContextCreator;
9+
using ShardingCore.Core.RuntimeContexts;
10+
using ShardingCore.Exceptions;
11+
using ShardingCore.Extensions;
12+
using ShardingCore.Helpers;
13+
14+
namespace ShardingCore.EFCores
15+
{
16+
public abstract class AbstractScriptMigrationGenerator
17+
{
18+
private readonly IShardingRuntimeContext _shardingRuntimeContext;
19+
20+
public AbstractScriptMigrationGenerator(IShardingRuntimeContext shardingRuntimeContext)
21+
{
22+
_shardingRuntimeContext = shardingRuntimeContext;
23+
}
24+
25+
public string GenerateScript()
26+
{
27+
var virtualDataSource = _shardingRuntimeContext.GetVirtualDataSource();
28+
var allDataSourceNames = virtualDataSource.GetAllDataSourceNames();
29+
var dbContextCreator = _shardingRuntimeContext.GetDbContextCreator();
30+
var shardingProvider = _shardingRuntimeContext.GetShardingProvider();
31+
var shardingConfigOptions = _shardingRuntimeContext.GetShardingConfigOptions();
32+
var defaultDataSourceName = virtualDataSource.DefaultDataSourceName;
33+
34+
using (var scope = shardingProvider.CreateScope())
35+
{
36+
using (var shellDbContext = dbContextCreator.GetShellDbContext(scope.ServiceProvider))
37+
{
38+
var parallelCount = shardingConfigOptions.MigrationParallelCount;
39+
if (parallelCount <= 0)
40+
{
41+
throw new ShardingCoreInvalidOperationException($"migration parallel count must >0");
42+
}
43+
44+
//默认数据源需要最后执行 否则可能会导致异常的情况下GetPendingMigrations为空
45+
var partitionMigrationUnits = allDataSourceNames.Where(o => o != defaultDataSourceName)
46+
.Partition(parallelCount);
47+
var scriptStringBuilder = new StringBuilder();
48+
foreach (var migrationUnits in partitionMigrationUnits)
49+
{
50+
var migrateUnits = migrationUnits.Select(o => new MigrateUnit(shellDbContext, o)).ToList();
51+
var scriptSql = ExecuteMigrateUnits(_shardingRuntimeContext, migrateUnits);
52+
scriptStringBuilder.AppendLine(scriptSql);
53+
}
54+
55+
//包含默认默认的单独最后一次处理
56+
if (allDataSourceNames.Contains(defaultDataSourceName))
57+
{
58+
var scriptSql = ExecuteMigrateUnits(_shardingRuntimeContext,
59+
new List<MigrateUnit>() { new MigrateUnit(shellDbContext, defaultDataSourceName) });
60+
scriptStringBuilder.AppendLine(scriptSql);
61+
}
62+
63+
return scriptStringBuilder.ToString();
64+
}
65+
}
66+
}
67+
68+
private string ExecuteMigrateUnits(IShardingRuntimeContext shardingRuntimeContext,
69+
List<MigrateUnit> migrateUnits)
70+
{
71+
var shardingMigrationManager = shardingRuntimeContext.GetShardingMigrationManager();
72+
var dbContextCreator = shardingRuntimeContext.GetDbContextCreator();
73+
var routeTailFactory = shardingRuntimeContext.GetRouteTailFactory();
74+
var migrateTasks = migrateUnits.Select(migrateUnit =>
75+
{
76+
return Task.Run(() =>
77+
{
78+
using (shardingMigrationManager.CreateScope())
79+
{
80+
shardingMigrationManager.Current.CurrentDataSourceName = migrateUnit.DataSourceName;
81+
82+
var dbContextOptions = DynamicShardingHelper.CreateShellDbContextOptions(shardingRuntimeContext,
83+
migrateUnit.ShellDbContext.GetType(),
84+
migrateUnit.DataSourceName);
85+
86+
using (var dbContext = dbContextCreator.CreateDbContext(migrateUnit.ShellDbContext,
87+
new ShardingDbContextOptions(dbContextOptions,
88+
routeTailFactory.Create(string.Empty, false))))
89+
{
90+
var migrator = dbContext.GetService<IMigrator>();
91+
return $"-- DataSource:{migrateUnit.DataSourceName}" + Environment.NewLine +
92+
GenerateScriptSql(migrator) +
93+
Environment.NewLine;
94+
}
95+
}
96+
});
97+
}).ToArray();
98+
var scripts = TaskHelper.WhenAllFastFail(migrateTasks).WaitAndUnwrapException();
99+
return string.Join(Environment.NewLine, scripts);
100+
}
101+
102+
protected abstract string GenerateScriptSql(IMigrator migrator);
103+
}
104+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#if EFCORE2
2+
using Microsoft.EntityFrameworkCore.Migrations;
3+
using ShardingCore.Core.RuntimeContexts;
4+
5+
namespace ShardingCore.EFCores
6+
{
7+
public sealed class ScriptMigrationGenerator:AbstractScriptMigrationGenerator
8+
{
9+
private readonly string _fromMigration;
10+
private readonly string _toMigration;
11+
private readonly bool _idempotent;
12+
13+
public ScriptMigrationGenerator(IShardingRuntimeContext shardingRuntimeContext, string fromMigration = null,
14+
string toMigration = null, bool idempotent = false) : base(shardingRuntimeContext)
15+
{
16+
_fromMigration = fromMigration;
17+
_toMigration = toMigration;
18+
_idempotent = idempotent;
19+
}
20+
21+
protected override string GenerateScriptSql(IMigrator migrator)
22+
{
23+
return migrator.GenerateScript(_fromMigration, _toMigration, _idempotent);
24+
}
25+
}
26+
}
27+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#if EFCORE3
2+
using Microsoft.EntityFrameworkCore.Migrations;
3+
using ShardingCore.Core.RuntimeContexts;
4+
5+
namespace ShardingCore.EFCores
6+
{
7+
public sealed class ScriptMigrationGenerator:AbstractScriptMigrationGenerator
8+
{
9+
private readonly string _fromMigration;
10+
private readonly string _toMigration;
11+
private readonly bool _idempotent;
12+
13+
public ScriptMigrationGenerator(IShardingRuntimeContext shardingRuntimeContext, string fromMigration = null,
14+
string toMigration = null, bool idempotent = false) : base(shardingRuntimeContext)
15+
{
16+
_fromMigration = fromMigration;
17+
_toMigration = toMigration;
18+
_idempotent = idempotent;
19+
}
20+
21+
protected override string GenerateScriptSql(IMigrator migrator)
22+
{
23+
return migrator.GenerateScript(_fromMigration, _toMigration, _idempotent);
24+
}
25+
}
26+
}
27+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#if EFCORE5
2+
using Microsoft.EntityFrameworkCore.Migrations;
3+
using ShardingCore.Core.RuntimeContexts;
4+
5+
namespace ShardingCore.EFCores
6+
{
7+
public sealed class ScriptMigrationGenerator:AbstractScriptMigrationGenerator
8+
{
9+
private readonly string _fromMigration;
10+
private readonly string _toMigration;
11+
private readonly MigrationsSqlGenerationOptions _options;
12+
13+
public ScriptMigrationGenerator(IShardingRuntimeContext shardingRuntimeContext, string fromMigration = null,
14+
string toMigration = null,
15+
MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default) : base(shardingRuntimeContext)
16+
{
17+
_fromMigration = fromMigration;
18+
_toMigration = toMigration;
19+
_options = options;
20+
}
21+
22+
protected override string GenerateScriptSql(IMigrator migrator)
23+
{
24+
return migrator.GenerateScript(_fromMigration, _toMigration, _options);
25+
}
26+
}
27+
}
28+
#endif

src/ShardingCore/EFCores/EFCore6x/ScriptMigrationGenerator.cs

+4-105
Original file line numberDiff line numberDiff line change
@@ -1,128 +1,27 @@
11
#if EFCORE6
2-
using System;
3-
using System.Collections.Generic;
4-
using System.Linq;
5-
using System.Text;
6-
using System.Threading;
7-
using System.Threading.Tasks;
8-
using Microsoft.EntityFrameworkCore;
9-
using Microsoft.EntityFrameworkCore.Infrastructure;
102
using Microsoft.EntityFrameworkCore.Migrations;
11-
using ShardingCore.Core.DbContextCreator;
123
using ShardingCore.Core.RuntimeContexts;
13-
using ShardingCore.Exceptions;
14-
using ShardingCore.Extensions;
15-
using ShardingCore.Helpers;
16-
using ShardingCore.Sharding.ShardingDbContextExecutors;
174

185
namespace ShardingCore.EFCores
196
{
20-
public sealed class ScriptMigrationGenerator
7+
public sealed class ScriptMigrationGenerator:AbstractScriptMigrationGenerator
218
{
22-
private readonly IShardingRuntimeContext _shardingRuntimeContext;
239
private readonly string _fromMigration;
2410
private readonly string _toMigration;
2511
private readonly MigrationsSqlGenerationOptions _options;
2612

2713
public ScriptMigrationGenerator(IShardingRuntimeContext shardingRuntimeContext, string fromMigration = null,
2814
string toMigration = null,
29-
MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
15+
MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default) : base(shardingRuntimeContext)
3016
{
31-
_shardingRuntimeContext = shardingRuntimeContext;
3217
_fromMigration = fromMigration;
3318
_toMigration = toMigration;
3419
_options = options;
3520
}
3621

37-
public string GenerateScript()
22+
protected override string GenerateScriptSql(IMigrator migrator)
3823
{
39-
var virtualDataSource = _shardingRuntimeContext.GetVirtualDataSource();
40-
var allDataSourceNames = virtualDataSource.GetAllDataSourceNames();
41-
var dbContextCreator = _shardingRuntimeContext.GetDbContextCreator();
42-
var shardingProvider = _shardingRuntimeContext.GetShardingProvider();
43-
var shardingConfigOptions = _shardingRuntimeContext.GetShardingConfigOptions();
44-
var defaultDataSourceName = virtualDataSource.DefaultDataSourceName;
45-
46-
using (var scope = shardingProvider.CreateScope())
47-
{
48-
using (var shellDbContext = dbContextCreator.GetShellDbContext(scope.ServiceProvider))
49-
{
50-
var parallelCount = shardingConfigOptions.MigrationParallelCount;
51-
if (parallelCount <= 0)
52-
{
53-
throw new ShardingCoreInvalidOperationException($"migration parallel count must >0");
54-
}
55-
56-
//默认数据源需要最后执行 否则可能会导致异常的情况下GetPendingMigrations为空
57-
var partitionMigrationUnits = allDataSourceNames.Where(o => o != defaultDataSourceName)
58-
.Partition(parallelCount);
59-
var scriptStringBuilder = new StringBuilder();
60-
foreach (var migrationUnits in partitionMigrationUnits)
61-
{
62-
var migrateUnits = migrationUnits.Select(o => new MigrateUnit(shellDbContext, o)).ToList();
63-
var scriptSql = ExecuteMigrateUnits(_shardingRuntimeContext, migrateUnits);
64-
scriptStringBuilder.AppendLine(scriptSql);
65-
}
66-
67-
//包含默认默认的单独最后一次处理
68-
if (allDataSourceNames.Contains(defaultDataSourceName))
69-
{
70-
var scriptSql = ExecuteMigrateUnits(_shardingRuntimeContext,
71-
new List<MigrateUnit>() { new MigrateUnit(shellDbContext, defaultDataSourceName) });
72-
scriptStringBuilder.AppendLine(scriptSql);
73-
}
74-
75-
return scriptStringBuilder.ToString();
76-
}
77-
}
78-
}
79-
80-
private string ExecuteMigrateUnits(IShardingRuntimeContext shardingRuntimeContext,
81-
List<MigrateUnit> migrateUnits)
82-
{
83-
var shardingMigrationManager = shardingRuntimeContext.GetShardingMigrationManager();
84-
var dbContextCreator = shardingRuntimeContext.GetDbContextCreator();
85-
var routeTailFactory = shardingRuntimeContext.GetRouteTailFactory();
86-
var migrateTasks = migrateUnits.Select(migrateUnit =>
87-
{
88-
return Task.Run(() =>
89-
{
90-
using (shardingMigrationManager.CreateScope())
91-
{
92-
shardingMigrationManager.Current.CurrentDataSourceName = migrateUnit.DataSourceName;
93-
94-
var dbContextOptions = CreateDbContextOptions(shardingRuntimeContext,
95-
migrateUnit.ShellDbContext.GetType(),
96-
migrateUnit.DataSourceName);
97-
98-
using (var dbContext = dbContextCreator.CreateDbContext(migrateUnit.ShellDbContext,
99-
new ShardingDbContextOptions(dbContextOptions,
100-
routeTailFactory.Create(string.Empty, false))))
101-
{
102-
var migrator = dbContext.GetService<IMigrator>();
103-
return $"-- DataSource:{migrateUnit.DataSourceName}" + Environment.NewLine +
104-
migrator.GenerateScript(_fromMigration, _toMigration, _options) +
105-
Environment.NewLine;
106-
}
107-
}
108-
});
109-
}).ToArray();
110-
var scripts = TaskHelper.WhenAllFastFail(migrateTasks).WaitAndUnwrapException();
111-
return string.Join(Environment.NewLine, scripts);
112-
}
113-
114-
private DbContextOptions CreateDbContextOptions(IShardingRuntimeContext shardingRuntimeContext,
115-
Type dbContextType, string dataSourceName)
116-
{
117-
var virtualDataSource = shardingRuntimeContext.GetVirtualDataSource();
118-
var shardingConfigOptions = shardingRuntimeContext.GetShardingConfigOptions();
119-
var dbContextOptionBuilder = DataSourceDbContext.CreateDbContextOptionBuilder(dbContextType);
120-
var connectionString = virtualDataSource.GetConnectionString(dataSourceName);
121-
virtualDataSource.UseDbContextOptionsBuilder(connectionString, dbContextOptionBuilder);
122-
shardingConfigOptions.ShardingMigrationConfigure?.Invoke(dbContextOptionBuilder);
123-
//迁移
124-
dbContextOptionBuilder.UseShardingOptions(shardingRuntimeContext);
125-
return dbContextOptionBuilder.Options;
24+
return migrator.GenerateScript(_fromMigration, _toMigration, _options);
12625
}
12726
}
12827
}

src/ShardingCore/EFCores/ShardingMigrator.cs

+11-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ public class ShardingMigrator:Migrator
3535
{
3636
private readonly IShardingRuntimeContext _shardingRuntimeContext;
3737

38+
#if !EFCORE2 && !EFCORE3 && !EFCORE5 && !EFCORE6
39+
error
40+
#endif
3841

3942
#if EFCORE6
4043
public ShardingMigrator(IShardingRuntimeContext shardingRuntimeContext,IMigrationsAssembly migrationsAssembly, IHistoryRepository historyRepository, IDatabaseCreator databaseCreator, IMigrationsSqlGenerator migrationsSqlGenerator, IRawSqlCommandBuilder rawSqlCommandBuilder, IMigrationCommandExecutor migrationCommandExecutor, IRelationalConnection connection, ISqlGenerationHelper sqlGenerationHelper, ICurrentDbContext currentContext, IModelRuntimeInitializer modelRuntimeInitializer, IDiagnosticsLogger<DbLoggerCategory.Migrations> logger, IRelationalCommandDiagnosticsLogger commandLogger, IDatabaseProvider databaseProvider) : base(migrationsAssembly, historyRepository, databaseCreator, migrationsSqlGenerator, rawSqlCommandBuilder, migrationCommandExecutor, connection, sqlGenerationHelper, currentContext, modelRuntimeInitializer, logger, commandLogger, databaseProvider)
@@ -78,13 +81,20 @@ public override void Migrate(string targetMigration = null)
7881
await DynamicShardingHelper.DynamicMigrateWithDataSourcesAsync(_shardingRuntimeContext, allDataSourceNames, null,cancellationToken);
7982

8083
}
81-
#if EFCORE6
84+
#if EFCORE6 || EFCORE5
8285

8386
public override string GenerateScript(string fromMigration = null, string toMigration = null,
8487
MigrationsSqlGenerationOptions options = MigrationsSqlGenerationOptions.Default)
8588
{
8689
return new ScriptMigrationGenerator(_shardingRuntimeContext, fromMigration, toMigration, options).GenerateScript();
8790
}
91+
#endif
92+
#if EFCORE3 || EFCORE2
93+
public override string GenerateScript(string fromMigration = null, string toMigration = null, bool idempotent = false)
94+
{
95+
return new ScriptMigrationGenerator(_shardingRuntimeContext, fromMigration, toMigration, idempotent).GenerateScript();
96+
}
97+
8898
#endif
8999
}
90100

src/ShardingCore/Helpers/DynamicShardingHelper.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public static async Task DynamicMigrateWithDataSourcesAsync(IShardingRuntimeCont
9898
{
9999
shardingMigrationManager.Current.CurrentDataSourceName = migrateUnit.DataSourceName;
100100

101-
var dbContextOptions = CreateDbContextOptions(shardingRuntimeContext,migrateUnit.ShellDbContext.GetType(),
101+
var dbContextOptions = CreateShellDbContextOptions(shardingRuntimeContext,migrateUnit.ShellDbContext.GetType(),
102102
migrateUnit.DataSourceName);
103103

104104
using (var dbContext = dbContextCreator.CreateDbContext(migrateUnit.ShellDbContext,
@@ -119,7 +119,7 @@ public static async Task DynamicMigrateWithDataSourcesAsync(IShardingRuntimeCont
119119
await TaskHelper.WhenAllFastFail(migrateTasks);
120120
}
121121

122-
private static DbContextOptions CreateDbContextOptions(IShardingRuntimeContext shardingRuntimeContext,Type dbContextType,string dataSourceName)
122+
public static DbContextOptions CreateShellDbContextOptions(IShardingRuntimeContext shardingRuntimeContext,Type dbContextType,string dataSourceName)
123123
{
124124
var virtualDataSource = shardingRuntimeContext.GetVirtualDataSource();
125125
var shardingConfigOptions = shardingRuntimeContext.GetShardingConfigOptions();

0 commit comments

Comments
 (0)