From 339b543477c9a1846baf0be23c4d302bd04edfb4 Mon Sep 17 00:00:00 2001 From: xuejiaming <326308290@qq.com> Date: Tue, 1 Nov 2022 13:46:52 +0800 Subject: [PATCH] =?UTF-8?q?[#215]=20=E5=B9=B6=E4=B8=94=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=A1=A5=E5=81=BF=E8=A1=A8+HasData=E7=9A=84bug=20=E5=8F=91?= =?UTF-8?q?=E5=B8=836.8.0.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nuget-publish.bat | 2 +- .../Controllers/WeatherForecastController.cs | 8 +- .../DbContexts/DefaultShardingDbContext.cs | 30 ++++---- .../SysUserModVirtualDataSourceRoute.cs | 4 +- samples/Sample.MySql/Startup.cs | 20 ++--- .../DefaultDataSourceInitializer.cs | 74 +++++++++++-------- .../Extensions/DbContextExtension.cs | 47 ++++++++++++ 7 files changed, 125 insertions(+), 60 deletions(-) diff --git a/nuget-publish.bat b/nuget-publish.bat index 5155d42c..c0442b61 100644 --- a/nuget-publish.bat +++ b/nuget-publish.bat @@ -1,6 +1,6 @@ :start ::定义版本 -set SHARDINGCORE=6.8.0.3 +set SHARDINGCORE=6.8.0.4 ::删除所有bin与obj下的文件 @echo off diff --git a/samples/Sample.MySql/Controllers/WeatherForecastController.cs b/samples/Sample.MySql/Controllers/WeatherForecastController.cs index 7df835c5..a40cbda6 100644 --- a/samples/Sample.MySql/Controllers/WeatherForecastController.cs +++ b/samples/Sample.MySql/Controllers/WeatherForecastController.cs @@ -87,10 +87,10 @@ namespace Sample.MySql.Controllers // using (var tran = _defaultTableDbContext.Database.BeginTransaction()) // { - SysUserMod? resultX123 = await _defaultTableDbContext.Set() - .Where(o => o.Id == "2").FirstOrDefaultAsync(); - _defaultTableDbContext.Update(resultX123); - _defaultTableDbContext.SaveChanges(); + // SysUserMod? resultX123 = await _defaultTableDbContext.Set() + // .Where(o => o.Id == "2").FirstOrDefaultAsync(); + // _defaultTableDbContext.Update(resultX123); + // _defaultTableDbContext.SaveChanges(); var resultX1 = await _defaultTableDbContext.Set() .Where(o => o.Id == "2" || o.Id == "3").GroupBy(o => new { o.Id,o.Name }) .Select(o => new diff --git a/samples/Sample.MySql/DbContexts/DefaultShardingDbContext.cs b/samples/Sample.MySql/DbContexts/DefaultShardingDbContext.cs index 95441bdd..c53e8aed 100644 --- a/samples/Sample.MySql/DbContexts/DefaultShardingDbContext.cs +++ b/samples/Sample.MySql/DbContexts/DefaultShardingDbContext.cs @@ -11,7 +11,7 @@ using ShardingCore.Sharding.Abstractions; namespace Sample.MySql.DbContexts { - public class DefaultShardingDbContext:AbstractShardingDbContext, IShardingTableDbContext + public class DefaultShardingDbContext : AbstractShardingDbContext, IShardingTableDbContext { public DefaultShardingDbContext(DbContextOptions options) : base(options) { @@ -20,14 +20,15 @@ namespace Sample.MySql.DbContexts //Database.SetCommandTimeout(30000); } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - base.OnConfiguring(optionsBuilder); - optionsBuilder.UseLazyLoadingProxies(); - } + // protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + // { + // base.OnConfiguring(optionsBuilder); + // optionsBuilder.UseLazyLoadingProxies(); + // } 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) { @@ -40,7 +41,7 @@ namespace Sample.MySql.DbContexts modelBuilder.Entity().HasData(new SysTest() { Id = "1", UserId = "123" }); } - + protected void ConfigureGlobalFilters(ModelBuilder modelBuilder, IMutableEntityType entityType) where TEntity : class { @@ -53,17 +54,18 @@ namespace Sample.MySql.DbContexts { Expression>? expression = null; if (typeof(TEntity) == typeof(SysTest)) - { + { expression = e => ((IUser)e).UserId == "123"; - - } if (typeof(TEntity) == typeof(SysUserMod)) - { + } + + if (typeof(TEntity) == typeof(SysUserMod)) + { expression = e => ((IAge)e).Age == 99; - } return expression; } + public IRouteTail RouteTail { get; set; } } -} +} \ No newline at end of file diff --git a/samples/Sample.MySql/Shardings/SysUserModVirtualDataSourceRoute.cs b/samples/Sample.MySql/Shardings/SysUserModVirtualDataSourceRoute.cs index eb8eb619..51d8c781 100644 --- a/samples/Sample.MySql/Shardings/SysUserModVirtualDataSourceRoute.cs +++ b/samples/Sample.MySql/Shardings/SysUserModVirtualDataSourceRoute.cs @@ -9,14 +9,14 @@ public class SysUserModVirtualDataSourceRoute:AbstractShardingOperatorVirtualDat { public override string ShardingKeyToDataSourceName(object shardingKey) { - return $"{shardingKey}"; + return $"{((string)shardingKey=="ds1"?"ds1":"ds2")}"; } public override List GetAllDataSourceNames() { return new List() { - "ds0", "ds1", "ds2" + "ds1", "ds2" }; } diff --git a/samples/Sample.MySql/Startup.cs b/samples/Sample.MySql/Startup.cs index 67844fc3..dfa04e99 100644 --- a/samples/Sample.MySql/Startup.cs +++ b/samples/Sample.MySql/Startup.cs @@ -103,8 +103,8 @@ namespace Sample.MySql o.AddShardingDataSourceRoute(); }).UseConfig(o => { - o.UseEntityFrameworkCoreProxies = true; - o.ThrowIfQueryRouteNotMatch = false; + // o.UseEntityFrameworkCoreProxies = true; + o.ThrowIfQueryRouteNotMatch = false; o.AutoUseWriteConnectionStringAfterWriteDb = true; o.UseShardingQuery((conStr, builder) => { @@ -185,14 +185,14 @@ namespace Sample.MySql // var shardingRuntimeContext = app.ApplicationServices.GetRequiredService(); // var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); // var entityMetadata = entityMetadataManager.TryGet(); - using (var scope = app.ApplicationServices.CreateScope()) - { - var defaultShardingDbContext = scope.ServiceProvider.GetService(); - // if (defaultShardingDbContext.Database.GetPendingMigrations().Any()) - { - defaultShardingDbContext.Database.Migrate(); - } - } + // using (var scope = app.ApplicationServices.CreateScope()) + // { + // var defaultShardingDbContext = scope.ServiceProvider.GetService(); + // // if (defaultShardingDbContext.Database.GetPendingMigrations().Any()) + // { + // defaultShardingDbContext.Database.Migrate(); + // } + // } app.ApplicationServices.UseAutoTryCompensateTable(); // using (var scope = app.ApplicationServices.CreateScope()) // { diff --git a/src/ShardingCore/DynamicDataSources/DefaultDataSourceInitializer.cs b/src/ShardingCore/DynamicDataSources/DefaultDataSourceInitializer.cs index 21b01614..9884a1e2 100644 --- a/src/ShardingCore/DynamicDataSources/DefaultDataSourceInitializer.cs +++ b/src/ShardingCore/DynamicDataSources/DefaultDataSourceInitializer.cs @@ -16,7 +16,6 @@ using ShardingCore.Core.VirtualRoutes.Abstractions; using ShardingCore.Core.VirtualRoutes.TableRoutes; using ShardingCore.Exceptions; using ShardingCore.Extensions; - using ShardingCore.Sharding.Abstractions; using ShardingCore.TableExists.Abstractions; @@ -24,7 +23,7 @@ namespace ShardingCore.DynamicDataSources { public class DataSourceInitializer : IDataSourceInitializer { - private readonly ILogger _logger ; + private readonly ILogger _logger; private readonly IShardingProvider _shardingProvider; private readonly IDbContextCreator _dbContextCreator; @@ -48,7 +47,7 @@ namespace ShardingCore.DynamicDataSources IEntityMetadataManager entityMetadataManager, IShardingTableCreator shardingTableCreator, ITableEnsureManager tableEnsureManager, - ILogger logger ) + ILogger logger) { _shardingProvider = shardingProvider; _dbContextCreator = dbContextCreator; @@ -63,7 +62,7 @@ namespace ShardingCore.DynamicDataSources _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()) { @@ -72,38 +71,32 @@ namespace ShardingCore.DynamicDataSources var isDefault = _virtualDataSource.IsDefault(dataSourceName); if (createDatabase) { - EnsureCreated(isDefault,shellDbContext,dataSourceName); + EnsureCreated(isDefault, shellDbContext, dataSourceName); } if (createTable) { - var existTables = _tableEnsureManager.GetExistTables((IShardingDbContext)shellDbContext,dataSourceName); + var existTables = + _tableEnsureManager.GetExistTables((IShardingDbContext)shellDbContext, dataSourceName); var allShardingEntities = _entityMetadataManager.GetAllShardingEntities(); foreach (var entityType in allShardingEntities) { - //如果是默认数据源 - if (_virtualDataSource.IsDefault(dataSourceName)) + var entityMetadata = _entityMetadataManager.TryGet(entityType); + if (entityMetadata.IsShardingDataSource()) { - if (_entityMetadataManager.IsShardingTable(entityType)) + var virtualDataSourceRoute = _dataSourceRouteManager.GetRoute(entityType); + //如果是分库对象就要判断是否含有当前数据源 + if (virtualDataSourceRoute.GetAllDataSourceNames().Contains(dataSourceName)) { - var virtualTableRoute = _tableRouteManager.GetRoute(entityType); - CreateDataTable(dataSourceName, virtualTableRoute, existTables); + CreateDataTable(dataSourceName, entityMetadata, existTables); } } + //不是分库对象 else { - //非默认数据源 - if (_entityMetadataManager.IsShardingDataSource(entityType)) + if (_virtualDataSource.IsDefault(dataSourceName)) { - var virtualDataSourceRoute = _dataSourceRouteManager.GetRoute(entityType); - if (virtualDataSourceRoute.GetAllDataSourceNames().Contains(dataSourceName)) - { - if (_entityMetadataManager.IsShardingTable(entityType)) - { - var virtualTableRoute = _tableRouteManager.GetRoute(entityType); - CreateDataTable(dataSourceName, virtualTableRoute,existTables); - } - } + CreateDataTable(dataSourceName, entityMetadata, existTables); } } } @@ -111,6 +104,7 @@ namespace ShardingCore.DynamicDataSources } } } + private void EnsureCreated(bool isDefault, DbContext context, string dataSourceName) { @@ -128,7 +122,7 @@ namespace ShardingCore.DynamicDataSources { dbContext.RemoveDbContextAllRelationModelWithoutShardingDataSourceOnly(); } - + dbContext.Database.EnsureCreated(); } } @@ -138,17 +132,18 @@ namespace ShardingCore.DynamicDataSources $"{nameof(IDbContextCreator)}.{nameof(IDbContextCreator.GetShellDbContext)} db context type not impl {nameof(IShardingDbContext)}"); } } - private void CreateDataTable(string dataSourceName, IVirtualTableRoute tableRoute, ISet existTables) + + // private void CreateDataTable(string dataSourceName, IVirtualTableRoute tableRoute, ISet existTables) + private void CreateDataTable(string dataSourceName, EntityMetadata entityMetadata, ISet existTables) { - var entityMetadata = tableRoute.EntityMetadata; - foreach (var tail in tableRoute.GetTails()) + if (!entityMetadata.IsShardingTable()) { - var physicTableName = $"{entityMetadata.LogicTableName}{entityMetadata.TableSeparator}{tail}"; + var physicTableName = $"{entityMetadata.LogicTableName}"; try { //添加物理表 if (!existTables.Contains(physicTableName)) - _tableCreator.CreateTable(dataSourceName, entityMetadata.EntityType, tail); + _tableCreator.CreateTable(dataSourceName, entityMetadata.EntityType, string.Empty); } 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."); + } + } + } + } } - } } \ No newline at end of file diff --git a/src/ShardingCore/Extensions/DbContextExtension.cs b/src/ShardingCore/Extensions/DbContextExtension.cs index 2a77c5c2..98d4f2c8 100644 --- a/src/ShardingCore/Extensions/DbContextExtension.cs +++ b/src/ShardingCore/Extensions/DbContextExtension.cs @@ -47,6 +47,14 @@ namespace ShardingCore.Extensions var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); #if NET6_0 + var entityTypes = contextModel.GetEntityTypes(); + foreach (var entityType in entityTypes) + { + if (entityType.GetFieldValue("_data") is List _data) + { + _data.Clear(); + } + } var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel; var valueTuples = 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 #if NET5_0 || NETSTANDARD2_1 + var entityTypes = contextModel.GetEntityTypes(); + foreach (var entityType in entityTypes) + { + if (entityType.GetFieldValue("_data") is List _data) + { + _data.Clear(); + } + } var contextModelRelationalModel = contextModel.RelationalModel as RelationalModel; var valueTuples = 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 var entityTypes = contextModel.GetFieldValue("_entityTypes") as SortedDictionary; + foreach (var entityType in entityTypes) + { + if (entityType.GetFieldValue("_data") is List _data) + { + _data.Clear(); + } + } var list = entityTypes.Where(o=>entityMetadataManager.IsShardingTable(o.Value.ClrType)).Select(o=>o.Key).ToList(); for (int i = 0; i < list.Count; i++) { @@ -124,6 +147,14 @@ namespace ShardingCore.Extensions var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); #if NET6_0 + var entityTypes = contextModel.GetEntityTypes(); + foreach (var entityType in entityTypes) + { + if (entityType.GetFieldValue("_data") is List _data) + { + _data.Clear(); + } + } var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel; 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(); @@ -133,6 +164,14 @@ namespace ShardingCore.Extensions } #endif #if NET5_0 || NETSTANDARD2_1 + var entityTypes = contextModel.GetEntityTypes(); + foreach (var entityType in entityTypes) + { + if (entityType.GetFieldValue("_data") is List _data) + { + _data.Clear(); + } + } var contextModelRelationalModel = contextModel.RelationalModel as RelationalModel; 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(); @@ -142,8 +181,16 @@ namespace ShardingCore.Extensions } #endif #if NETCOREAPP2_0 || NETSTANDARD2_0 || NETCOREAPP3_0 + var entityTypes = contextModel.GetFieldValue("_entityTypes") as SortedDictionary; + foreach (var entityType in entityTypes) + { + if (entityType.GetFieldValue("_data") is List _data) + { + _data.Clear(); + } + } 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++) {