[#215] 并且修复补偿表+HasData的bug 发布6.8.0.4

This commit is contained in:
xuejiaming 2022-11-01 13:46:52 +08:00
parent c34b3a816d
commit 339b543477
7 changed files with 125 additions and 60 deletions

View File

@ -1,6 +1,6 @@
:start :start
::定义版本 ::定义版本
set SHARDINGCORE=6.8.0.3 set SHARDINGCORE=6.8.0.4
::删除所有bin与obj下的文件 ::删除所有bin与obj下的文件
@echo off @echo off

View File

@ -87,10 +87,10 @@ namespace Sample.MySql.Controllers
// using (var tran = _defaultTableDbContext.Database.BeginTransaction()) // using (var tran = _defaultTableDbContext.Database.BeginTransaction())
// { // {
SysUserMod? resultX123 = await _defaultTableDbContext.Set<SysUserMod>() // SysUserMod? resultX123 = await _defaultTableDbContext.Set<SysUserMod>()
.Where(o => o.Id == "2").FirstOrDefaultAsync(); // .Where(o => o.Id == "2").FirstOrDefaultAsync();
_defaultTableDbContext.Update(resultX123); // _defaultTableDbContext.Update(resultX123);
_defaultTableDbContext.SaveChanges(); // _defaultTableDbContext.SaveChanges();
var resultX1 = await _defaultTableDbContext.Set<SysUserMod>() var resultX1 = await _defaultTableDbContext.Set<SysUserMod>()
.Where(o => o.Id == "2" || o.Id == "3").GroupBy(o => new { o.Id,o.Name }) .Where(o => o.Id == "2" || o.Id == "3").GroupBy(o => new { o.Id,o.Name })
.Select(o => new .Select(o => new

View File

@ -11,7 +11,7 @@ using ShardingCore.Sharding.Abstractions;
namespace Sample.MySql.DbContexts namespace Sample.MySql.DbContexts
{ {
public class DefaultShardingDbContext:AbstractShardingDbContext, IShardingTableDbContext public class DefaultShardingDbContext : AbstractShardingDbContext, IShardingTableDbContext
{ {
public DefaultShardingDbContext(DbContextOptions<DefaultShardingDbContext> options) : base(options) public DefaultShardingDbContext(DbContextOptions<DefaultShardingDbContext> options) : base(options)
{ {
@ -20,14 +20,15 @@ namespace Sample.MySql.DbContexts
//Database.SetCommandTimeout(30000); //Database.SetCommandTimeout(30000);
} }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) // protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{ // {
base.OnConfiguring(optionsBuilder); // base.OnConfiguring(optionsBuilder);
optionsBuilder.UseLazyLoadingProxies(); // optionsBuilder.UseLazyLoadingProxies();
} // }
private readonly MethodInfo? _configureGlobalFiltersMethodInfo = private readonly MethodInfo? _configureGlobalFiltersMethodInfo =
typeof(DefaultShardingDbContext).GetMethod(nameof(ConfigureGlobalFilters), BindingFlags.Instance | BindingFlags.NonPublic); typeof(DefaultShardingDbContext).GetMethod(nameof(ConfigureGlobalFilters),
BindingFlags.Instance | BindingFlags.NonPublic);
protected override void OnModelCreating(ModelBuilder modelBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder)
{ {
@ -40,7 +41,7 @@ namespace Sample.MySql.DbContexts
modelBuilder.Entity<SysTest>().HasData(new SysTest() { Id = "1", UserId = "123" }); modelBuilder.Entity<SysTest>().HasData(new SysTest() { Id = "1", UserId = "123" });
} }
protected void ConfigureGlobalFilters<TEntity>(ModelBuilder modelBuilder, IMutableEntityType entityType) protected void ConfigureGlobalFilters<TEntity>(ModelBuilder modelBuilder, IMutableEntityType entityType)
where TEntity : class where TEntity : class
{ {
@ -53,17 +54,18 @@ namespace Sample.MySql.DbContexts
{ {
Expression<Func<TEntity, bool>>? expression = null; Expression<Func<TEntity, bool>>? expression = null;
if (typeof(TEntity) == typeof(SysTest)) if (typeof(TEntity) == typeof(SysTest))
{ {
expression = e => ((IUser)e).UserId == "123"; expression = e => ((IUser)e).UserId == "123";
}
} if (typeof(TEntity) == typeof(SysUserMod))
{ if (typeof(TEntity) == typeof(SysUserMod))
{
expression = e => ((IAge)e).Age == 99; expression = e => ((IAge)e).Age == 99;
} }
return expression; return expression;
} }
public IRouteTail RouteTail { get; set; } public IRouteTail RouteTail { get; set; }
} }
} }

View File

@ -9,14 +9,14 @@ public class SysUserModVirtualDataSourceRoute:AbstractShardingOperatorVirtualDat
{ {
public override string ShardingKeyToDataSourceName(object shardingKey) public override string ShardingKeyToDataSourceName(object shardingKey)
{ {
return $"{shardingKey}"; return $"{((string)shardingKey=="ds1"?"ds1":"ds2")}";
} }
public override List<string> GetAllDataSourceNames() public override List<string> GetAllDataSourceNames()
{ {
return new List<string>() return new List<string>()
{ {
"ds0", "ds1", "ds2" "ds1", "ds2"
}; };
} }

View File

@ -103,8 +103,8 @@ namespace Sample.MySql
o.AddShardingDataSourceRoute<SysUserModVirtualDataSourceRoute>(); o.AddShardingDataSourceRoute<SysUserModVirtualDataSourceRoute>();
}).UseConfig(o => }).UseConfig(o =>
{ {
o.UseEntityFrameworkCoreProxies = true; // o.UseEntityFrameworkCoreProxies = true;
o.ThrowIfQueryRouteNotMatch = false; o.ThrowIfQueryRouteNotMatch = false;
o.AutoUseWriteConnectionStringAfterWriteDb = true; o.AutoUseWriteConnectionStringAfterWriteDb = true;
o.UseShardingQuery((conStr, builder) => o.UseShardingQuery((conStr, builder) =>
{ {
@ -185,14 +185,14 @@ namespace Sample.MySql
// var shardingRuntimeContext = app.ApplicationServices.GetRequiredService<IShardingRuntimeContext>(); // var shardingRuntimeContext = app.ApplicationServices.GetRequiredService<IShardingRuntimeContext>();
// var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); // var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
// var entityMetadata = entityMetadataManager.TryGet<SysUserMod>(); // var entityMetadata = entityMetadataManager.TryGet<SysUserMod>();
using (var scope = app.ApplicationServices.CreateScope()) // using (var scope = app.ApplicationServices.CreateScope())
{ // {
var defaultShardingDbContext = scope.ServiceProvider.GetService<DefaultShardingDbContext>(); // var defaultShardingDbContext = scope.ServiceProvider.GetService<DefaultShardingDbContext>();
// if (defaultShardingDbContext.Database.GetPendingMigrations().Any()) // // if (defaultShardingDbContext.Database.GetPendingMigrations().Any())
{ // {
defaultShardingDbContext.Database.Migrate(); // defaultShardingDbContext.Database.Migrate();
} // }
} // }
app.ApplicationServices.UseAutoTryCompensateTable(); app.ApplicationServices.UseAutoTryCompensateTable();
// using (var scope = app.ApplicationServices.CreateScope()) // using (var scope = app.ApplicationServices.CreateScope())
// { // {

View File

@ -16,7 +16,6 @@ using ShardingCore.Core.VirtualRoutes.Abstractions;
using ShardingCore.Core.VirtualRoutes.TableRoutes; using ShardingCore.Core.VirtualRoutes.TableRoutes;
using ShardingCore.Exceptions; using ShardingCore.Exceptions;
using ShardingCore.Extensions; using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions; using ShardingCore.Sharding.Abstractions;
using ShardingCore.TableExists.Abstractions; using ShardingCore.TableExists.Abstractions;
@ -24,7 +23,7 @@ namespace ShardingCore.DynamicDataSources
{ {
public class DataSourceInitializer : IDataSourceInitializer public class DataSourceInitializer : IDataSourceInitializer
{ {
private readonly ILogger<DataSourceInitializer> _logger ; private readonly ILogger<DataSourceInitializer> _logger;
private readonly IShardingProvider _shardingProvider; private readonly IShardingProvider _shardingProvider;
private readonly IDbContextCreator _dbContextCreator; private readonly IDbContextCreator _dbContextCreator;
@ -48,7 +47,7 @@ namespace ShardingCore.DynamicDataSources
IEntityMetadataManager entityMetadataManager, IEntityMetadataManager entityMetadataManager,
IShardingTableCreator shardingTableCreator, IShardingTableCreator shardingTableCreator,
ITableEnsureManager tableEnsureManager, ITableEnsureManager tableEnsureManager,
ILogger<DataSourceInitializer> logger ) ILogger<DataSourceInitializer> logger)
{ {
_shardingProvider = shardingProvider; _shardingProvider = shardingProvider;
_dbContextCreator = dbContextCreator; _dbContextCreator = dbContextCreator;
@ -63,7 +62,7 @@ namespace ShardingCore.DynamicDataSources
_logger = logger; _logger = logger;
} }
public void InitConfigure(string dataSourceName,bool createDatabase,bool createTable) public void InitConfigure(string dataSourceName, bool createDatabase, bool createTable)
{ {
using (var shardingScope = _shardingProvider.CreateScope()) using (var shardingScope = _shardingProvider.CreateScope())
{ {
@ -72,38 +71,32 @@ namespace ShardingCore.DynamicDataSources
var isDefault = _virtualDataSource.IsDefault(dataSourceName); var isDefault = _virtualDataSource.IsDefault(dataSourceName);
if (createDatabase) if (createDatabase)
{ {
EnsureCreated(isDefault,shellDbContext,dataSourceName); EnsureCreated(isDefault, shellDbContext, dataSourceName);
} }
if (createTable) if (createTable)
{ {
var existTables = _tableEnsureManager.GetExistTables((IShardingDbContext)shellDbContext,dataSourceName); var existTables =
_tableEnsureManager.GetExistTables((IShardingDbContext)shellDbContext, dataSourceName);
var allShardingEntities = _entityMetadataManager.GetAllShardingEntities(); var allShardingEntities = _entityMetadataManager.GetAllShardingEntities();
foreach (var entityType in allShardingEntities) foreach (var entityType in allShardingEntities)
{ {
//如果是默认数据源 var entityMetadata = _entityMetadataManager.TryGet(entityType);
if (_virtualDataSource.IsDefault(dataSourceName)) if (entityMetadata.IsShardingDataSource())
{ {
if (_entityMetadataManager.IsShardingTable(entityType)) var virtualDataSourceRoute = _dataSourceRouteManager.GetRoute(entityType);
//如果是分库对象就要判断是否含有当前数据源
if (virtualDataSourceRoute.GetAllDataSourceNames().Contains(dataSourceName))
{ {
var virtualTableRoute = _tableRouteManager.GetRoute(entityType); CreateDataTable(dataSourceName, entityMetadata, existTables);
CreateDataTable(dataSourceName, virtualTableRoute, existTables);
} }
} }
//不是分库对象
else else
{ {
//非默认数据源 if (_virtualDataSource.IsDefault(dataSourceName))
if (_entityMetadataManager.IsShardingDataSource(entityType))
{ {
var virtualDataSourceRoute = _dataSourceRouteManager.GetRoute(entityType); CreateDataTable(dataSourceName, entityMetadata, existTables);
if (virtualDataSourceRoute.GetAllDataSourceNames().Contains(dataSourceName))
{
if (_entityMetadataManager.IsShardingTable(entityType))
{
var virtualTableRoute = _tableRouteManager.GetRoute(entityType);
CreateDataTable(dataSourceName, virtualTableRoute,existTables);
}
}
} }
} }
} }
@ -111,6 +104,7 @@ namespace ShardingCore.DynamicDataSources
} }
} }
} }
private void EnsureCreated(bool isDefault, DbContext context, private void EnsureCreated(bool isDefault, DbContext context,
string dataSourceName) string dataSourceName)
{ {
@ -128,7 +122,7 @@ namespace ShardingCore.DynamicDataSources
{ {
dbContext.RemoveDbContextAllRelationModelWithoutShardingDataSourceOnly(); dbContext.RemoveDbContextAllRelationModelWithoutShardingDataSourceOnly();
} }
dbContext.Database.EnsureCreated(); dbContext.Database.EnsureCreated();
} }
} }
@ -138,17 +132,18 @@ namespace ShardingCore.DynamicDataSources
$"{nameof(IDbContextCreator)}.{nameof(IDbContextCreator.GetShellDbContext)} db context type not impl {nameof(IShardingDbContext)}"); $"{nameof(IDbContextCreator)}.{nameof(IDbContextCreator.GetShellDbContext)} db context type not impl {nameof(IShardingDbContext)}");
} }
} }
private void CreateDataTable(string dataSourceName, IVirtualTableRoute tableRoute, ISet<string> existTables)
// private void CreateDataTable(string dataSourceName, IVirtualTableRoute tableRoute, ISet<string> existTables)
private void CreateDataTable(string dataSourceName, EntityMetadata entityMetadata, ISet<string> existTables)
{ {
var entityMetadata = tableRoute.EntityMetadata; if (!entityMetadata.IsShardingTable())
foreach (var tail in tableRoute.GetTails())
{ {
var physicTableName = $"{entityMetadata.LogicTableName}{entityMetadata.TableSeparator}{tail}"; var physicTableName = $"{entityMetadata.LogicTableName}";
try try
{ {
//添加物理表 //添加物理表
if (!existTables.Contains(physicTableName)) if (!existTables.Contains(physicTableName))
_tableCreator.CreateTable(dataSourceName, entityMetadata.EntityType, tail); _tableCreator.CreateTable(dataSourceName, entityMetadata.EntityType, string.Empty);
} }
catch (Exception e) catch (Exception e)
{ {
@ -159,7 +154,28 @@ namespace ShardingCore.DynamicDataSources
} }
} }
} }
else
{
var tableRoute = _tableRouteManager.GetRoute(entityMetadata.EntityType);
foreach (var tail in tableRoute.GetTails())
{
var physicTableName = $"{entityMetadata.LogicTableName}{entityMetadata.TableSeparator}{tail}";
try
{
//添加物理表
if (!existTables.Contains(physicTableName))
_tableCreator.CreateTable(dataSourceName, entityMetadata.EntityType, tail);
}
catch (Exception e)
{
if (!_shardingConfigOptions.IgnoreCreateTableError.GetValueOrDefault())
{
_logger.LogWarning(e,
$"table :{physicTableName} will created.");
}
}
}
}
} }
} }
} }

View File

@ -47,6 +47,14 @@ namespace ShardingCore.Extensions
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
#if NET6_0 #if NET6_0
var entityTypes = contextModel.GetEntityTypes();
foreach (var entityType in entityTypes)
{
if (entityType.GetFieldValue("_data") is List<object> _data)
{
_data.Clear();
}
}
var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel; var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel;
var valueTuples = var valueTuples =
contextModelRelationalModel.Tables.Where(o =>o.Value.EntityTypeMappings.Any(m => entityMetadataManager.IsShardingTable(m.EntityType.ClrType))).Select(o => o.Key).ToList(); contextModelRelationalModel.Tables.Where(o =>o.Value.EntityTypeMappings.Any(m => entityMetadataManager.IsShardingTable(m.EntityType.ClrType))).Select(o => o.Key).ToList();
@ -56,6 +64,14 @@ namespace ShardingCore.Extensions
} }
#endif #endif
#if NET5_0 || NETSTANDARD2_1 #if NET5_0 || NETSTANDARD2_1
var entityTypes = contextModel.GetEntityTypes();
foreach (var entityType in entityTypes)
{
if (entityType.GetFieldValue("_data") is List<object> _data)
{
_data.Clear();
}
}
var contextModelRelationalModel = contextModel.RelationalModel as RelationalModel; var contextModelRelationalModel = contextModel.RelationalModel as RelationalModel;
var valueTuples = var valueTuples =
contextModelRelationalModel.Tables.Where(o => o.Value.EntityTypeMappings.Any(m => entityMetadataManager.IsShardingTable(m.EntityType.ClrType))).Select(o => o.Key).ToList(); contextModelRelationalModel.Tables.Where(o => o.Value.EntityTypeMappings.Any(m => entityMetadataManager.IsShardingTable(m.EntityType.ClrType))).Select(o => o.Key).ToList();
@ -67,6 +83,13 @@ namespace ShardingCore.Extensions
#if NETCOREAPP2_0 || NETSTANDARD2_0 || NETCOREAPP3_0 #if NETCOREAPP2_0 || NETSTANDARD2_0 || NETCOREAPP3_0
var entityTypes = var entityTypes =
contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>; contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>;
foreach (var entityType in entityTypes)
{
if (entityType.GetFieldValue("_data") is List<object> _data)
{
_data.Clear();
}
}
var list = entityTypes.Where(o=>entityMetadataManager.IsShardingTable(o.Value.ClrType)).Select(o=>o.Key).ToList(); var list = entityTypes.Where(o=>entityMetadataManager.IsShardingTable(o.Value.ClrType)).Select(o=>o.Key).ToList();
for (int i = 0; i < list.Count; i++) for (int i = 0; i < list.Count; i++)
{ {
@ -124,6 +147,14 @@ namespace ShardingCore.Extensions
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
#if NET6_0 #if NET6_0
var entityTypes = contextModel.GetEntityTypes();
foreach (var entityType in entityTypes)
{
if (entityType.GetFieldValue("_data") is List<object> _data)
{
_data.Clear();
}
}
var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel; var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel;
var valueTuples = var valueTuples =
contextModelRelationalModel.Tables.Where(o => o.Value.EntityTypeMappings.Any(m => !entityMetadataManager.IsShardingDataSource(m.EntityType.ClrType) ||entityMetadataManager.TryGet(m.EntityType.ClrType)==null)).Select(o => o.Key).ToList(); contextModelRelationalModel.Tables.Where(o => o.Value.EntityTypeMappings.Any(m => !entityMetadataManager.IsShardingDataSource(m.EntityType.ClrType) ||entityMetadataManager.TryGet(m.EntityType.ClrType)==null)).Select(o => o.Key).ToList();
@ -133,6 +164,14 @@ namespace ShardingCore.Extensions
} }
#endif #endif
#if NET5_0 || NETSTANDARD2_1 #if NET5_0 || NETSTANDARD2_1
var entityTypes = contextModel.GetEntityTypes();
foreach (var entityType in entityTypes)
{
if (entityType.GetFieldValue("_data") is List<object> _data)
{
_data.Clear();
}
}
var contextModelRelationalModel = contextModel.RelationalModel as RelationalModel; var contextModelRelationalModel = contextModel.RelationalModel as RelationalModel;
var valueTuples = var valueTuples =
contextModelRelationalModel.Tables.Where(o => o.Value.EntityTypeMappings.Any(m => !entityMetadataManager.IsShardingDataSource(m.EntityType.ClrType)||entityMetadataManager.TryGet(m.EntityType.ClrType)==null)).Select(o => o.Key).ToList(); contextModelRelationalModel.Tables.Where(o => o.Value.EntityTypeMappings.Any(m => !entityMetadataManager.IsShardingDataSource(m.EntityType.ClrType)||entityMetadataManager.TryGet(m.EntityType.ClrType)==null)).Select(o => o.Key).ToList();
@ -142,8 +181,16 @@ namespace ShardingCore.Extensions
} }
#endif #endif
#if NETCOREAPP2_0 || NETSTANDARD2_0 || NETCOREAPP3_0 #if NETCOREAPP2_0 || NETSTANDARD2_0 || NETCOREAPP3_0
var entityTypes = var entityTypes =
contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>; contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>;
foreach (var entityType in entityTypes)
{
if (entityType.GetFieldValue("_data") is List<object> _data)
{
_data.Clear();
}
}
var list = entityTypes.Where(o => !entityMetadataManager.IsShardingDataSource(o.Value.ClrType) || entityMetadataManager.TryGet(o.Value.ClrType) == null).Select(o => o.Key).ToList(); var list = entityTypes.Where(o => !entityMetadataManager.IsShardingDataSource(o.Value.ClrType) || entityMetadataManager.TryGet(o.Value.ClrType) == null).Select(o => o.Key).ToList();
for (int i = 0; i < list.Count; i++) for (int i = 0; i < list.Count; i++)
{ {