private static List <string> BuildShardingCmds(MigrationOperation operation, string sourceCmd, ISqlGenerationHelper sqlGenerationHelper) { //所有MigrationOperation定义 //https://github.com/dotnet/efcore/tree/b970bf29a46521f40862a01db9e276e6448d3cb0/src/EFCore.Relational/Migrations/Operations //ColumnOperation仅替换Table //其余其余都是将Name和Table使用分表名替换 Dictionary <string, List <string> > _existsShardingTables = Cache.ServiceProvider.GetService <ShardingContainer>().ExistsShardingTables; List <string> resList = new List <string>(); 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 <KeyValuePair <string, List <string> >, bool> where = x => _existsShardingTables.Any(x => Regex.IsMatch(name, BuildPattern(x.Key))); if (!tableName.IsNullOrEmpty()) { absTableName = tableName; } else if (!name.IsNullOrEmpty() && _existsShardingTables.Any(x => where (x))) { absTableName = _existsShardingTables.Where(x => where (x)).FirstOrDefault().Key; } //分表 if (!absTableName.IsNullOrEmpty() && _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 void ReplaceName(MigrationOperation theOperation, string sourceName, string targetName) { string name = theOperation.GetPropertyValue("Name") as string; string tableName = theOperation.GetPropertyValue("Table") as string; if (!tableName.IsNullOrEmpty()) { theOperation.SetPropertyValue("Table", targetName); } if (!name.IsNullOrEmpty() && !(theOperation is ColumnOperation)) { string[] patterns = new string[] { $"^()({sourceName})()$", $"^()({sourceName})(_.*?)$", $"^(.*?_)({sourceName})(_.*?)$", $"^(.*?_)({sourceName})()$" }; foreach (var aPattern in patterns) { if (Regex.IsMatch(name, aPattern)) { var newName = new Regex(aPattern).Replace(name, "${1}" + targetName + "$3"); theOperation.SetPropertyValue("Name", newName); break; } } } Func <PropertyInfo, bool> propertyWhere = x => x.PropertyType.IsGenericType && x.PropertyType.GetGenericTypeDefinition() == typeof(List <>) && typeof(MigrationOperation).IsAssignableFrom(x.PropertyType.GetGenericArguments()[0]); //其它 theOperation.GetType().GetProperties() .Where(x => x.Name != "Name" && x.Name != "Table" && x.PropertyType != typeof(object) && (typeof(MigrationOperation).IsAssignableFrom(x.PropertyType) || propertyWhere(x)) ) .ToList() .ForEach(aProperty => { var propertyValue = aProperty.GetValue(theOperation); if (propertyValue is MigrationOperation propertyOperation) { ReplaceName(propertyOperation, sourceName, targetName); } else if (propertyWhere(aProperty)) { foreach (var aValue in (IEnumerable)propertyValue) { ReplaceName((MigrationOperation)aValue, sourceName, targetName); } } }); }
private List <MigrationOperation> BuildShardingOperation(MigrationOperation sourceOperation) { //所有MigrationOperation定义 //https://github.com/dotnet/efcore/tree/b970bf29a46521f40862a01db9e276e6448d3cb0/src/EFCore.Relational/Migrations/Operations //ColumnOperation仅替换Table //其余其余都是将Name和Table使用分表名替换 List <MigrationOperation> resList = new List <MigrationOperation>(); string absTableName = string.Empty; string name = sourceOperation.GetPropertyValue("Name") as string; string tableName = sourceOperation.GetPropertyValue("Table") as string; string pattern = string.Format("^({0})$|^({0}_.*?)$|^(.*?_{0}_.*?)$|^(.*?_{0})$", absTableName); Func <KeyValuePair <string, List <string> >, bool> where = x => _existsShardingTables.Any(x => Regex.IsMatch(name, BuildPattern(x.Key))); if (!tableName.IsNullOrEmpty()) { absTableName = tableName; } else if (!name.IsNullOrEmpty() && _existsShardingTables.Any(x => where (x))) { absTableName = _existsShardingTables.Where(x => where (x)).FirstOrDefault().Key; } //分表 if (!absTableName.IsNullOrEmpty() && _existsShardingTables.ContainsKey(absTableName)) { var shardings = _existsShardingTables[absTableName]; shardings.ForEach(aSharding => { var clone = sourceOperation.DeepClone(); resList.Add(clone); ReplaceName(clone, absTableName, aSharding); }); } //不分表 else { resList.Add(sourceOperation); } 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 (!name.IsNullOrEmpty() && !(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 <PropertyInfo, bool> 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); } }