完成按需创建表的demo
This commit is contained in:
parent
41972bbd82
commit
84326c2552
|
@ -1,153 +1,123 @@
|
|||
// using System.Collections.Concurrent;
|
||||
// using System.Linq.Expressions;
|
||||
// using MySqlConnector;
|
||||
// using Newtonsoft.Json;
|
||||
// using ShardingCore.Core.EntityMetadatas;
|
||||
// using ShardingCore.Core.PhysicTables;
|
||||
// using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
// using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
// using ShardingCore.Core.VirtualRoutes;
|
||||
// using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
// using ShardingCore.Exceptions;
|
||||
// using ShardingCore.Extensions;
|
||||
// using ShardingCore.TableCreator;
|
||||
//
|
||||
// namespace Sample.AutoCreateIfPresent
|
||||
// {
|
||||
// public class AreaDeviceRoute : AbstractShardingOperatorVirtualTableRoute<AreaDevice, string>
|
||||
// {
|
||||
// private const string Tables = "Tables";
|
||||
// private const string TABLE_SCHEMA = "TABLE_SCHEMA";
|
||||
// private const string TABLE_NAME = "TABLE_NAME";
|
||||
//
|
||||
// private const string CurrentTableName = nameof(AreaDevice);
|
||||
// private readonly IVirtualDataSourceManager<DefaultDbContext> _virtualDataSourceManager;
|
||||
// private readonly IVirtualTableManager<DefaultDbContext> _virtualTableManager;
|
||||
// private readonly IShardingTableCreator<DefaultDbContext> _shardingTableCreator;
|
||||
// private readonly ConcurrentDictionary<string, object?> _tails = new ConcurrentDictionary<string, object?>();
|
||||
// private readonly object _lock = new object();
|
||||
//
|
||||
// public AreaDeviceRoute(IVirtualDataSourceManager<DefaultDbContext> virtualDataSourceManager, IVirtualTableManager<DefaultDbContext> virtualTableManager, IShardingTableCreator<DefaultDbContext> shardingTableCreator)
|
||||
// {
|
||||
// _virtualDataSourceManager = virtualDataSourceManager;
|
||||
// _virtualTableManager = virtualTableManager;
|
||||
// _shardingTableCreator = shardingTableCreator;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public override string ShardingKeyToTail(object shardingKey)
|
||||
// {
|
||||
// return $"{shardingKey}";
|
||||
// }
|
||||
// /// <summary>
|
||||
// /// 如果你是非mysql数据库请自行实现这个方法返回当前类在数据库已经存在的后缀
|
||||
// /// 仅启动时调用
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// public override List<string> GetAllTails()
|
||||
// {
|
||||
// //启动寻找有哪些表后缀
|
||||
// using (var connection = new MySqlConnection(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultConnectionString))
|
||||
// {
|
||||
// connection.Open();
|
||||
// var database = connection.Database;
|
||||
//
|
||||
// using (var dataTable = connection.GetSchema(Tables))
|
||||
// {
|
||||
// for (int i = 0; i < dataTable.Rows.Count; i++)
|
||||
// {
|
||||
// var schema = dataTable.Rows[i][TABLE_SCHEMA];
|
||||
// if (database.Equals($"{schema}", StringComparison.OrdinalIgnoreCase))
|
||||
// {
|
||||
// var tableName = dataTable.Rows[i][TABLE_NAME]?.ToString() ?? string.Empty;
|
||||
// if (tableName.StartsWith(CurrentTableName,StringComparison.OrdinalIgnoreCase))
|
||||
// {
|
||||
// //如果没有下划线那么需要CurrentTableName.Length有下划线就要CurrentTableName.Length+1
|
||||
// _tails.TryAdd(tableName.Substring(CurrentTableName.Length+1), null);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return _tails.Keys.ToList();
|
||||
// }
|
||||
//
|
||||
// public override void Configure(EntityMetadataTableBuilder<AreaDevice> builder)
|
||||
// {
|
||||
// builder.ShardingProperty(o => o.Area);
|
||||
// }
|
||||
//
|
||||
// public override Func<string, bool> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
|
||||
// {
|
||||
// var t = ShardingKeyToTail(shardingKey);
|
||||
// switch (shardingOperator)
|
||||
// {
|
||||
// case ShardingOperatorEnum.Equal: return tail => tail == t;
|
||||
// default:
|
||||
// {
|
||||
// #if DEBUG
|
||||
// Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
||||
// #endif
|
||||
// return tail => true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public override IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey)
|
||||
// {
|
||||
// var shardingKeyToTail = ShardingKeyToTail(shardingKey);
|
||||
//
|
||||
// if (!_tails.TryGetValue(shardingKeyToTail, out var _))
|
||||
// {
|
||||
// lock (_lock)
|
||||
// {
|
||||
// if (!_tails.TryGetValue(shardingKeyToTail, out var _))
|
||||
// {
|
||||
// var virtualTable = _virtualTableManager.GetVirtualTable(typeof(AreaDevice));
|
||||
// _virtualTableManager.AddPhysicTable(virtualTable, new DefaultPhysicTable(virtualTable, shardingKeyToTail));
|
||||
// try
|
||||
// {
|
||||
// _shardingTableCreator.CreateTable<AreaDevice>(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultDataSourceName, shardingKeyToTail);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine("尝试添加表失败" + ex);
|
||||
// }
|
||||
//
|
||||
// _tails.TryAdd(shardingKeyToTail, null);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// var needRefresh = allPhysicTables.Count != _tails.Count;
|
||||
// if (needRefresh)
|
||||
// {
|
||||
// var virtualTable = _virtualTableManager.GetVirtualTable(typeof(AreaDevice));
|
||||
// //修复可能导致迭代器遍历时添加的bug
|
||||
// var keys = _tails.Keys.ToList();
|
||||
// foreach (var tail in keys)
|
||||
// {
|
||||
// var hashSet = allPhysicTables.Select(o => o.Tail).ToHashSet();
|
||||
// if (!hashSet.Contains(tail))
|
||||
// {
|
||||
// var tables = virtualTable.GetAllPhysicTables();
|
||||
// var physicTable = tables.FirstOrDefault(o => o.Tail == tail);
|
||||
// if (physicTable != null)
|
||||
// {
|
||||
// allPhysicTables.Add(physicTable);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// var physicTables = allPhysicTables.Where(o => o.Tail == shardingKeyToTail).ToList();
|
||||
// if (physicTables.IsEmpty())
|
||||
// {
|
||||
// throw new ShardingCoreException($"sharding key route not match {EntityMetadata.EntityType} -> [{EntityMetadata.ShardingTableProperty.Name}] ->【{shardingKey}】 all tails ->[{string.Join(",", allPhysicTables.Select(o => o.FullName))}]");
|
||||
// }
|
||||
//
|
||||
// if (physicTables.Count > 1)
|
||||
// throw new ShardingCoreException($"more than one route match table:{string.Join(",", physicTables.Select(o => $"[{o.FullName}]"))}");
|
||||
// return physicTables[0];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
using System.Collections.Concurrent;
|
||||
using MySqlConnector;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
using ShardingCore.TableCreator;
|
||||
|
||||
namespace Sample.AutoCreateIfPresent
|
||||
{
|
||||
public class AreaDeviceRoute : AbstractShardingOperatorVirtualTableRoute<AreaDevice, string>
|
||||
{
|
||||
private readonly IVirtualDataSource _virtualDataSource;
|
||||
private readonly IShardingTableCreator _tableCreator;
|
||||
private const string Tables = "Tables";
|
||||
private const string TABLE_SCHEMA = "TABLE_SCHEMA";
|
||||
private const string TABLE_NAME = "TABLE_NAME";
|
||||
|
||||
private const string CurrentTableName = nameof(AreaDevice);
|
||||
|
||||
private readonly ConcurrentDictionary<string, object?> _tails = new ConcurrentDictionary<string, object?>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly object _lock = new object();
|
||||
|
||||
public AreaDeviceRoute(IVirtualDataSource virtualDataSource, IShardingTableCreator tableCreator)
|
||||
{
|
||||
_virtualDataSource = virtualDataSource;
|
||||
_tableCreator = tableCreator;
|
||||
InitTails();
|
||||
}
|
||||
|
||||
private void InitTails()
|
||||
{
|
||||
|
||||
using (var connection = new MySqlConnection(_virtualDataSource.DefaultConnectionString))
|
||||
{
|
||||
connection.Open();
|
||||
var database = connection.Database;
|
||||
|
||||
using (var dataTable = connection.GetSchema(Tables))
|
||||
{
|
||||
for (int i = 0; i < dataTable.Rows.Count; i++)
|
||||
{
|
||||
var schema = dataTable.Rows[i][TABLE_SCHEMA];
|
||||
if (database.Equals($"{schema}", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var tableName = dataTable.Rows[i][TABLE_NAME]?.ToString() ?? string.Empty;
|
||||
if (tableName.StartsWith(CurrentTableName,StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//如果没有下划线那么需要CurrentTableName.Length有下划线就要CurrentTableName.Length+1
|
||||
_tails.TryAdd(tableName.Substring(CurrentTableName.Length+1), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override string ShardingKeyToTail(object shardingKey)
|
||||
{
|
||||
return $"{shardingKey}";
|
||||
}
|
||||
/// <summary>
|
||||
/// 如果你是非mysql数据库请自行实现这个方法返回当前类在数据库已经存在的后缀
|
||||
/// 仅启动时调用
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override List<string> GetTails()
|
||||
{
|
||||
return _tails.Keys.ToList();
|
||||
}
|
||||
|
||||
public override void Configure(EntityMetadataTableBuilder<AreaDevice> builder)
|
||||
{
|
||||
builder.ShardingProperty(o => o.Area);
|
||||
}
|
||||
|
||||
public override Func<string, bool> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
|
||||
{
|
||||
var t = ShardingKeyToTail(shardingKey);
|
||||
switch (shardingOperator)
|
||||
{
|
||||
case ShardingOperatorEnum.Equal: return tail => tail == t;
|
||||
default:
|
||||
{
|
||||
#if DEBUG
|
||||
Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
||||
#endif
|
||||
return tail => true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override TableRouteUnit RouteWithValue(DataSourceRouteResult dataSourceRouteResult, object shardingKey)
|
||||
{
|
||||
var shardingKeyToTail = ShardingKeyToTail(shardingKey);
|
||||
if (!_tails.TryGetValue(shardingKeyToTail, out var _))
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (!_tails.TryGetValue(shardingKeyToTail, out var _))
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
_tableCreator.CreateTable<AreaDevice>(_virtualDataSource.DefaultDataSourceName,
|
||||
shardingKeyToTail);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("尝试添加表失败" + ex);
|
||||
}
|
||||
|
||||
_tails.TryAdd(shardingKeyToTail, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return base.RouteWithValue(dataSourceRouteResult, shardingKey);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,184 +1,150 @@
|
|||
// using System;
|
||||
// using System.Collections.Concurrent;
|
||||
// using System.Linq.Expressions;
|
||||
// using MySqlConnector;
|
||||
// using ShardingCore;
|
||||
// using ShardingCore.Core.EntityMetadatas;
|
||||
// using ShardingCore.Core.PhysicTables;
|
||||
// using ShardingCore.Core.ShardingConfigurations;
|
||||
// using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
// using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
// using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
// using ShardingCore.Core.VirtualRoutes;
|
||||
// using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
// using ShardingCore.Exceptions;
|
||||
// using ShardingCore.Extensions;
|
||||
// using ShardingCore.TableCreator;
|
||||
// using ShardingCore.TableExists;
|
||||
//
|
||||
// /*
|
||||
// * @Author: xjm
|
||||
// * @Description:
|
||||
// * @Date: DATE
|
||||
// * @Email: 326308290@qq.com
|
||||
// */
|
||||
// namespace Sample.AutoCreateIfPresent
|
||||
// {
|
||||
// public class OrderByHourRoute : AbstractShardingOperatorVirtualTableRoute<OrderByHour, DateTime>
|
||||
// {
|
||||
// private const string Tables = "Tables";
|
||||
// private const string TABLE_SCHEMA = "TABLE_SCHEMA";
|
||||
// private const string TABLE_NAME = "TABLE_NAME";
|
||||
//
|
||||
// private const string CurrentTableName = nameof(OrderByHour);
|
||||
// private readonly IVirtualDataSourceManager<DefaultDbContext> _virtualDataSourceManager;
|
||||
// private readonly IVirtualTableManager<DefaultDbContext> _virtualTableManager;
|
||||
// private readonly IShardingTableCreator<DefaultDbContext> _shardingTableCreator;
|
||||
// private readonly ConcurrentDictionary<string, object?> _tails = new ConcurrentDictionary<string, object?>();
|
||||
// private readonly object _lock = new object();
|
||||
//
|
||||
// public OrderByHourRoute(IVirtualDataSourceManager<DefaultDbContext> virtualDataSourceManager,IVirtualTableManager<DefaultDbContext> virtualTableManager, IShardingTableCreator<DefaultDbContext> shardingTableCreator)
|
||||
// {
|
||||
// _virtualDataSourceManager = virtualDataSourceManager;
|
||||
// _virtualTableManager = virtualTableManager;
|
||||
// _shardingTableCreator = shardingTableCreator;
|
||||
// }
|
||||
//
|
||||
// public override string ShardingKeyToTail(object shardingKey)
|
||||
// {
|
||||
// var dateTime = (DateTime)shardingKey;
|
||||
// return ShardingKeyFormat(dateTime);
|
||||
// }
|
||||
// private string ShardingKeyFormat(DateTime dateTime)
|
||||
// {
|
||||
// var tail = $"{dateTime:yyyyMMddHH}";
|
||||
//
|
||||
// return tail;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 如果你是非mysql数据库请自行实现这个方法返回当前类在数据库已经存在的后缀
|
||||
// /// 仅启动时调用
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// public override List<string> GetTails()
|
||||
// {
|
||||
// //启动寻找有哪些表后缀
|
||||
// using (var connection = new MySqlConnection(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultConnectionString))
|
||||
// {
|
||||
// connection.Open();
|
||||
// var database = connection.Database;
|
||||
//
|
||||
// using (var dataTable = connection.GetSchema(Tables))
|
||||
// {
|
||||
// for (int i = 0; i < dataTable.Rows.Count; i++)
|
||||
// {
|
||||
// var schema = dataTable.Rows[i][TABLE_SCHEMA];
|
||||
// if (database.Equals($"{schema}", StringComparison.OrdinalIgnoreCase))
|
||||
// {
|
||||
// var tableName = dataTable.Rows[i][TABLE_NAME]?.ToString()??string.Empty;
|
||||
// if (tableName.StartsWith(CurrentTableName, StringComparison.OrdinalIgnoreCase))
|
||||
// {
|
||||
// //如果没有下划线那么需要CurrentTableName.Length有下划线就要CurrentTableName.Length+1
|
||||
// _tails.TryAdd(tableName.Substring(CurrentTableName.Length+1),null);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return _tails.Keys.ToList();
|
||||
// }
|
||||
//
|
||||
// public override void Configure(EntityMetadataTableBuilder<OrderByHour> builder)
|
||||
// {
|
||||
// builder.ShardingProperty(o => o.CreateTime);
|
||||
// }
|
||||
//
|
||||
// public override Func<string, bool> GetRouteToFilter(DateTime shardingKey, ShardingOperatorEnum shardingOperator)
|
||||
// {
|
||||
// var t = ShardingKeyFormat(shardingKey);
|
||||
// switch (shardingOperator)
|
||||
// {
|
||||
// case ShardingOperatorEnum.GreaterThan:
|
||||
// case ShardingOperatorEnum.GreaterThanOrEqual:
|
||||
// return tail => String.Compare(tail, t, StringComparison.Ordinal) >= 0;
|
||||
// case ShardingOperatorEnum.LessThan:
|
||||
// {
|
||||
// var currentHourBeginTime = new DateTime(shardingKey.Year,shardingKey.Month,shardingKey.Day,shardingKey.Hour,0,0);
|
||||
// //处于临界值 o=>o.time < [2021-01-01 00:00:00] 尾巴20210101不应该被返回
|
||||
// if (currentHourBeginTime == shardingKey)
|
||||
// return tail => String.Compare(tail, t, StringComparison.Ordinal) < 0;
|
||||
// return tail => String.Compare(tail, t, StringComparison.Ordinal) <= 0;
|
||||
// }
|
||||
// case ShardingOperatorEnum.LessThanOrEqual:
|
||||
// return tail => String.Compare(tail, t, StringComparison.Ordinal) <= 0;
|
||||
// case ShardingOperatorEnum.Equal: return tail => tail == t;
|
||||
// default:
|
||||
// {
|
||||
// #if DEBUG
|
||||
// Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
||||
// #endif
|
||||
// return tail => true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public override IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey)
|
||||
// {
|
||||
// var shardingKeyToTail = ShardingKeyToTail(shardingKey);
|
||||
//
|
||||
// if (!_tails.TryGetValue(shardingKeyToTail,out var _))
|
||||
// {
|
||||
// lock (_lock)
|
||||
// {
|
||||
// if (!_tails.TryGetValue(shardingKeyToTail,out var _))
|
||||
// {
|
||||
// var virtualTable = _virtualTableManager.GetVirtualTable(typeof(OrderByHour));
|
||||
// //必须先执行AddPhysicTable在进行CreateTable
|
||||
// _virtualTableManager.AddPhysicTable(virtualTable, new DefaultPhysicTable(virtualTable, shardingKeyToTail));
|
||||
// try
|
||||
// {
|
||||
// _shardingTableCreator.CreateTable<OrderByHour>(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultDataSourceName, shardingKeyToTail);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine("尝试添加表失败" + ex);
|
||||
// }
|
||||
//
|
||||
// _tails.TryAdd(shardingKeyToTail,null);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// var needRefresh = allPhysicTables.Count != _tails.Count;
|
||||
// if (needRefresh)
|
||||
// {
|
||||
// var virtualTable = _virtualTableManager.GetVirtualTable(typeof(OrderByHour));
|
||||
// //修复可能导致迭代器遍历时添加的bug
|
||||
// var keys = _tails.Keys.ToList();
|
||||
// foreach (var tail in keys)
|
||||
// {
|
||||
// var hashSet = allPhysicTables.Select(o=>o.Tail).ToHashSet();
|
||||
// if (!hashSet.Contains(tail))
|
||||
// {
|
||||
// var tables = virtualTable.GetAllPhysicTables();
|
||||
// var physicTable = tables.FirstOrDefault(o=>o.Tail==tail);
|
||||
// if (physicTable!= null)
|
||||
// {
|
||||
// allPhysicTables.Add(physicTable);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// var physicTables = allPhysicTables.Where(o => o.Tail== shardingKeyToTail).ToList();
|
||||
// if (physicTables.IsEmpty())
|
||||
// {
|
||||
// throw new ShardingCoreException($"sharding key route not match {EntityMetadata.EntityType} -> [{EntityMetadata.ShardingTableProperty.Name}] ->【{shardingKey}】 all tails ->[{string.Join(",", allPhysicTables.Select(o=>o.FullName))}]");
|
||||
// }
|
||||
//
|
||||
// if (physicTables.Count > 1)
|
||||
// throw new ShardingCoreException($"more than one route match table:{string.Join(",", physicTables.Select(o => $"[{o.FullName}]"))}");
|
||||
// return physicTables[0];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using MySqlConnector;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
using ShardingCore.TableCreator;
|
||||
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: DATE
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
namespace Sample.AutoCreateIfPresent
|
||||
{
|
||||
public class OrderByHourRoute : AbstractShardingOperatorVirtualTableRoute<OrderByHour, DateTime>
|
||||
{
|
||||
private const string Tables = "Tables";
|
||||
private const string TABLE_SCHEMA = "TABLE_SCHEMA";
|
||||
private const string TABLE_NAME = "TABLE_NAME";
|
||||
|
||||
private const string CurrentTableName = nameof(OrderByHour);
|
||||
private readonly IVirtualDataSource _virtualDataSource;
|
||||
private readonly IShardingTableCreator _shardingTableCreator;
|
||||
private readonly ConcurrentDictionary<string, object?> _tails = new ConcurrentDictionary<string, object?>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly object _lock = new object();
|
||||
|
||||
public OrderByHourRoute(IVirtualDataSource virtualDataSource, IShardingTableCreator shardingTableCreator)
|
||||
{
|
||||
_virtualDataSource = virtualDataSource;
|
||||
_shardingTableCreator = shardingTableCreator;
|
||||
InitTails();
|
||||
}
|
||||
|
||||
private void InitTails()
|
||||
{
|
||||
|
||||
//启动寻找有哪些表后缀
|
||||
using (var connection = new MySqlConnection(_virtualDataSource.DefaultConnectionString))
|
||||
{
|
||||
connection.Open();
|
||||
var database = connection.Database;
|
||||
|
||||
using (var dataTable = connection.GetSchema(Tables))
|
||||
{
|
||||
for (int i = 0; i < dataTable.Rows.Count; i++)
|
||||
{
|
||||
var schema = dataTable.Rows[i][TABLE_SCHEMA];
|
||||
if (database.Equals($"{schema}", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var tableName = dataTable.Rows[i][TABLE_NAME]?.ToString()??string.Empty;
|
||||
if (tableName.StartsWith(CurrentTableName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
//如果没有下划线那么需要CurrentTableName.Length有下划线就要CurrentTableName.Length+1
|
||||
_tails.TryAdd(tableName.Substring(CurrentTableName.Length+1),null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ShardingKeyToTail(object shardingKey)
|
||||
{
|
||||
var dateTime = (DateTime)shardingKey;
|
||||
return ShardingKeyFormat(dateTime);
|
||||
}
|
||||
private string ShardingKeyFormat(DateTime dateTime)
|
||||
{
|
||||
var tail = $"{dateTime:yyyyMMddHH}";
|
||||
|
||||
return tail;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 如果你是非mysql数据库请自行实现这个方法返回当前类在数据库已经存在的后缀
|
||||
/// 仅启动时调用
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override List<string> GetTails()
|
||||
{
|
||||
return _tails.Keys.ToList();
|
||||
}
|
||||
|
||||
public override void Configure(EntityMetadataTableBuilder<OrderByHour> builder)
|
||||
{
|
||||
builder.ShardingProperty(o => o.CreateTime);
|
||||
}
|
||||
|
||||
public override Func<string, bool> GetRouteToFilter(DateTime shardingKey, ShardingOperatorEnum shardingOperator)
|
||||
{
|
||||
var t = ShardingKeyFormat(shardingKey);
|
||||
switch (shardingOperator)
|
||||
{
|
||||
case ShardingOperatorEnum.GreaterThan:
|
||||
case ShardingOperatorEnum.GreaterThanOrEqual:
|
||||
return tail => String.Compare(tail, t, StringComparison.Ordinal) >= 0;
|
||||
case ShardingOperatorEnum.LessThan:
|
||||
{
|
||||
var currentHourBeginTime = new DateTime(shardingKey.Year,shardingKey.Month,shardingKey.Day,shardingKey.Hour,0,0);
|
||||
//处于临界值 o=>o.time < [2021-01-01 00:00:00] 尾巴20210101不应该被返回
|
||||
if (currentHourBeginTime == shardingKey)
|
||||
return tail => String.Compare(tail, t, StringComparison.Ordinal) < 0;
|
||||
return tail => String.Compare(tail, t, StringComparison.Ordinal) <= 0;
|
||||
}
|
||||
case ShardingOperatorEnum.LessThanOrEqual:
|
||||
return tail => String.Compare(tail, t, StringComparison.Ordinal) <= 0;
|
||||
case ShardingOperatorEnum.Equal: return tail => tail == t;
|
||||
default:
|
||||
{
|
||||
#if DEBUG
|
||||
Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
||||
#endif
|
||||
return tail => true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override TableRouteUnit RouteWithValue(DataSourceRouteResult dataSourceRouteResult, object shardingKey)
|
||||
{
|
||||
var shardingKeyToTail = ShardingKeyToTail(shardingKey);
|
||||
|
||||
if (!_tails.TryGetValue(shardingKeyToTail, out var _))
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (!_tails.TryGetValue(shardingKeyToTail, out var _))
|
||||
{
|
||||
try
|
||||
{
|
||||
_shardingTableCreator.CreateTable<OrderByHour>(_virtualDataSource.DefaultDataSourceName,
|
||||
shardingKeyToTail);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("尝试添加表失败" + ex);
|
||||
}
|
||||
|
||||
_tails.TryAdd(shardingKeyToTail, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return base.RouteWithValue(dataSourceRouteResult, shardingKey);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,8 +21,8 @@ builder.Services.AddControllers();
|
|||
builder.Services.AddShardingDbContext<DefaultDbContext>()
|
||||
.AddEntityConfig(o =>
|
||||
{
|
||||
// o.AddShardingTableRoute<OrderByHourRoute>();
|
||||
// o.AddShardingTableRoute<AreaDeviceRoute>();
|
||||
o.AddShardingTableRoute<OrderByHourRoute>();
|
||||
o.AddShardingTableRoute<AreaDeviceRoute>();
|
||||
})
|
||||
.AddConfig(o =>
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@ using Microsoft.EntityFrameworkCore;
|
|||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Sample.MySql.DbContexts;
|
||||
using Sample.MySql.Domain.Entities;
|
||||
using ShardingCore.Extensions.ShardingQueryableExtensions;
|
||||
using ShardingCore.TableCreator;
|
||||
|
||||
namespace Sample.MySql.Controllers
|
||||
|
@ -31,7 +32,8 @@ namespace Sample.MySql.Controllers
|
|||
// using (var tran = _defaultTableDbContext.Database.BeginTransaction())
|
||||
// {
|
||||
|
||||
var resultX = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "2" || o.Id == "3").FirstOrDefaultAsync();
|
||||
var resultX = await _defaultTableDbContext.Set<SysUserMod>()
|
||||
.Where(o => o.Id == "2" || o.Id == "3").FirstOrDefaultAsync();
|
||||
var resultY = await _defaultTableDbContext.Set<SysUserMod>().FirstOrDefaultAsync(o => o.Id == "2" || o.Id == "3");
|
||||
var result = await _defaultTableDbContext.Set<SysTest>().AnyAsync();
|
||||
var result1 = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "2" || o.Id == "3").ToListAsync();
|
||||
|
|
|
@ -4,12 +4,20 @@ using System.Linq;
|
|||
using System.Threading.Tasks;
|
||||
using Sample.MySql.Domain.Entities;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.VirtualRoutes.Months;
|
||||
|
||||
namespace Sample.MySql.Shardings
|
||||
{
|
||||
public class SysUserLogByMonthRoute:AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute<SysUserLogByMonth>
|
||||
{
|
||||
private readonly ILogger<SysUserLogByMonthRoute> _logger;
|
||||
|
||||
public SysUserLogByMonthRoute(ILogger<SysUserLogByMonthRoute> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
public override DateTime GetBeginTime()
|
||||
{
|
||||
return new DateTime(2021, 1, 01);
|
||||
|
@ -24,5 +32,18 @@ namespace Sample.MySql.Shardings
|
|||
{
|
||||
builder.ShardingProperty(o => o.Time);
|
||||
}
|
||||
|
||||
protected override List<TableRouteUnit> AfterShardingRouteUnitFilter(DataSourceRouteResult dataSourceRouteResult, List<TableRouteUnit> shardingRouteUnits)
|
||||
{
|
||||
if (shardingRouteUnits.Count > 10)
|
||||
{
|
||||
_logger.LogInformation("截断前:"+string.Join(",",shardingRouteUnits.Select(o=>o.Tail)));
|
||||
//这边你要自己做顺序处理阶段
|
||||
var result= shardingRouteUnits.OrderByDescending(o=>o.Tail).Take(10).ToList();
|
||||
_logger.LogInformation("截断后:"+string.Join(",",result.Select(o=>o.Tail)));
|
||||
return result;
|
||||
}
|
||||
return base.AfterShardingRouteUnitFilter(dataSourceRouteResult, shardingRouteUnits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace ShardingCore.Helpers
|
|||
}
|
||||
public static long ConvertDateTimeToLong(DateTime localDateTime)
|
||||
{
|
||||
return new DateTimeOffset(localDateTime).ToUnixTimeMilliseconds(); ;
|
||||
return new DateTimeOffset(localDateTime).ToUnixTimeMilliseconds();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -94,21 +94,23 @@ namespace ShardingCore.CommonTest
|
|||
var obj1 = new {time=new DateTime(2022, 1, 2)};
|
||||
var queryables=new List<IQueryable<TestTimeEntity>>()
|
||||
{
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time==queryTime),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=queryTime&&o.Time<queryTime2),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=queryTime&&o.Time<queryTime3),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=queryTime&&o.Time<=queryTime3),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time==queryTime1),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>queryTime==o.Time),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time.Equals(queryTime)),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>queryTime.Equals(o.Time)),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time==obj1.time),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time.Equals(obj1.time)),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>obj1.time.Equals(o.Time)),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>times.Contains(o.Time)),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>new []{queryTime}.Contains(o.Time)),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>times1.Contains(o.Time)),
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=> new List<DateTime>(){queryTime}.Contains(o.Time))
|
||||
|
||||
new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time==times[0]),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time==queryTime),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=queryTime&&o.Time<queryTime2),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=queryTime&&o.Time<queryTime3),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time>=queryTime&&o.Time<=queryTime3),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time==queryTime1),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>queryTime==o.Time),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time.Equals(queryTime)),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>queryTime.Equals(o.Time)),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time==obj1.time),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>o.Time.Equals(obj1.time)),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>obj1.time.Equals(o.Time)),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>times.Contains(o.Time)),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>new []{queryTime}.Contains(o.Time)),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=>times1.Contains(o.Time)),
|
||||
// new List<TestTimeEntity>().AsQueryable().Where(o=> new List<DateTime>(){queryTime}.Contains(o.Time))
|
||||
};
|
||||
TestFor(queryables,tables);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue