Closed carldai0106 closed 1 year ago
不是回复过你了吗,通过自定义分表实现
新建一个类继承 ORM自带的 DateSplitTableService 这个类重写内部方法 ,然后用自定分表就可以实了
大佬,我都不知道是不是我错了。请看下我重写的类。
public class StationSplitService : ISplitTableService
{
/// <summary>
/// 返回数据库中所有分表
/// </summary>
public List<SplitTableInfo> GetAllTables(ISqlSugarClient db, EntityInfo EntityInfo, List<DbTableInfo> tableInfos)
{
var result = new List<SplitTableInfo>();
var regex = EntityInfo.DbTableName.Replace("{ssid}", "[0-9]{1,}");
var currentTables = tableInfos.Where(it => Regex.IsMatch(it.Name, regex, RegexOptions.IgnoreCase))
.Select(it => it.Name).Reverse().ToList();
foreach (var item in currentTables)
{
var data = new SplitTableInfo()
{
TableName = item
};
result.Add(data);
}
return result.OrderBy(it => it.TableName).ToList();
}
public object GetFieldValue(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object entityValue)
{
var splitColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyInfo.GetCustomAttribute<SplitFieldAttribute>() != null);
var value = splitColumn.PropertyInfo.GetValue(entityValue, null);
return value;
}
public string GetTableName(ISqlSugarClient db, EntityInfo entityInfo)
{
var id = db.Queryable<h_station>().OrderBy(x => x.ID, OrderByType.Asc).Select(x => x.ID).FirstAsync();
return entityInfo.DbTableName.Replace("{ssid}", id.ToString());
}
public string GetTableName(ISqlSugarClient db, EntityInfo entityInfo, SplitType type)
{
var id = db.Queryable<h_station>().OrderBy(x => x.ID, OrderByType.Asc).Select(x => x.ID).FirstAsync();
return entityInfo.DbTableName.Replace("{ssid}", id.ToString());
}
public string GetTableName(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object fieldValue)
{
if (fieldValue == null)
{
var name = entityInfo.DbTableName.Replace("_{ssid}", "");
return name;
}
return entityInfo.DbTableName.Replace("{ssid}", fieldValue.ToString());
}
}
下面这个方法传入的第三个参数:List<DbTableInfo> tableInfos 是不是来自这个查询:select TABLE_NAME as Name,TABLE_COMMENT as Description from information_schema.tables where TABLE_SCHEMA=(select database()) AND TABLE_TYPE='BASE TABLE'
/// <summary>
/// 返回数据库中所有分表
/// </summary>
public List<SplitTableInfo> GetAllTables(ISqlSugarClient db, EntityInfo EntityInfo, List<DbTableInfo> tableInfos)
{
var result = new List<SplitTableInfo>();
var regex = EntityInfo.DbTableName.Replace("{ssid}", "[0-9]{1,}");
var currentTables = tableInfos.Where(it => Regex.IsMatch(it.Name, regex, RegexOptions.IgnoreCase))
.Select(it => it.Name).Reverse().ToList();
foreach (var item in currentTables)
{
var data = new SplitTableInfo()
{
TableName = item
};
result.Add(data);
}
return result.OrderBy(it => it.TableName).ToList();
}
然后这里会不会返回 所有表
DbContext.SplitHelper
会不会调用这个查询语句:select TABLE_NAME as Name,TABLE_COMMENT as Description from information_schema.tables where TABLE_SCHEMA=(select database()) AND TABLE_TYPE='BASE TABLE
这个查询会不会调用获取所有表的查询语句: .SplitTable(tabs => tabs.Take(3))
DbContext.Queryable
只要您说不会调用,我就不纠结了。谢谢,浪费了您的宝贵时间。
知道你的意思了,源码加了个事件 StaticConfig.SplitTableGetTablesFunc=xxx 你在程序启动时给这个委托重新赋值就行了
好的,感谢回复。我试试,非常感谢。我可能不怎么会表达需求。
我在论坛中提过2次问题,最后都不了了之,应该是我没有描述清楚。 我大概看了下源码,发现所有的分表逻辑都会去调用原生sql语句去获取数据库创建的用户表信息: 查询的SQL语句是:
如果数据库中创建的用户表很多,会导致查询很慢,会加一个系统锁,锁的耗时大约是 1~2秒,当在k8s中开启一个应用的多个实例,每个实例中有多个线程在同步数据的时候,数据库监控端可以看到非常多的系统锁。会严重拖慢数据库的响应速度。 我尝试过实现 接口:ISplitTableService 但是没用,还是会调用 这个函数
实现的接口函数:
List<DbTableInfo> tableInfos 这里的信息就是来自 GetTables()。
其他实现的3个获取表名函数:GetTableName 这个可以不用从 GetTables() 去获取。 我是希望作者可以不写死 GetTables() 函数,可以从某个地方传一个参数,可以定时去拉取数据库的用户表信息。 而不是每次都去拉取。