代码完成编译
This commit is contained in:
parent
d18ba69dfc
commit
89a8e66a6f
|
@ -2,8 +2,6 @@
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using ShardingCore;
|
using ShardingCore;
|
||||||
using ShardingCore.Bootstrappers;
|
|
||||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
using ShardingCore6x.NoShardingDbContexts;
|
using ShardingCore6x.NoShardingDbContexts;
|
||||||
using ShardingCore6x.ShardingDbContexts;
|
using ShardingCore6x.ShardingDbContexts;
|
||||||
|
@ -16,7 +14,6 @@ namespace ShardingCore6x
|
||||||
{
|
{
|
||||||
private readonly DefaultDbContext _defaultDbContext;
|
private readonly DefaultDbContext _defaultDbContext;
|
||||||
private readonly DefaultShardingDbContext _defaultShardingDbContext;
|
private readonly DefaultShardingDbContext _defaultShardingDbContext;
|
||||||
private readonly IVirtualTableManager<DefaultShardingDbContext> _virtualTableManager;
|
|
||||||
public EFCoreCrud()
|
public EFCoreCrud()
|
||||||
{
|
{
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
|
@ -30,13 +27,10 @@ namespace ShardingCore6x
|
||||||
services.AddShardingDbContext<DefaultShardingDbContext>(ServiceLifetime.Transient, ServiceLifetime.Transient)
|
services.AddShardingDbContext<DefaultShardingDbContext>(ServiceLifetime.Transient, ServiceLifetime.Transient)
|
||||||
.AddEntityConfig(o =>
|
.AddEntityConfig(o =>
|
||||||
{
|
{
|
||||||
o.CreateShardingTableOnStart = true;
|
|
||||||
o.EnsureCreatedWithOutShardingTable = true;
|
|
||||||
o.AddShardingTableRoute<OrderVirtualTableRoute>();
|
o.AddShardingTableRoute<OrderVirtualTableRoute>();
|
||||||
})
|
})
|
||||||
.AddConfig(op =>
|
.AddConfig(op =>
|
||||||
{
|
{
|
||||||
op.ConfigId = "c1";
|
|
||||||
op.UseShardingQuery((conStr, builder) =>
|
op.UseShardingQuery((conStr, builder) =>
|
||||||
{
|
{
|
||||||
builder.UseSqlServer(conStr);
|
builder.UseSqlServer(conStr);
|
||||||
|
@ -55,7 +49,8 @@ namespace ShardingCore6x
|
||||||
}).EnsureConfig();
|
}).EnsureConfig();
|
||||||
|
|
||||||
var buildServiceProvider = services.BuildServiceProvider();
|
var buildServiceProvider = services.BuildServiceProvider();
|
||||||
buildServiceProvider.GetRequiredService<IShardingBootstrapper>().Start();
|
buildServiceProvider.UseAutoShardingCreate();
|
||||||
|
buildServiceProvider.UseAutoTryCompensateTable();
|
||||||
ICollection<Order> orders = new LinkedList<Order>();
|
ICollection<Order> orders = new LinkedList<Order>();
|
||||||
|
|
||||||
using (var scope = buildServiceProvider.CreateScope())
|
using (var scope = buildServiceProvider.CreateScope())
|
||||||
|
@ -106,9 +101,8 @@ namespace ShardingCore6x
|
||||||
Console.WriteLine($"批量插入订单数据:{orders.Count},用时:{sp.ElapsedMilliseconds}");
|
Console.WriteLine($"批量插入订单数据:{orders.Count},用时:{sp.ElapsedMilliseconds}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_defaultDbContext = ShardingContainer.GetService<DefaultDbContext>();
|
_defaultDbContext = buildServiceProvider.GetService<DefaultDbContext>();
|
||||||
_defaultShardingDbContext = ShardingContainer.GetService<DefaultShardingDbContext>();
|
_defaultShardingDbContext = buildServiceProvider.GetService<DefaultShardingDbContext>();
|
||||||
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<DefaultShardingDbContext>>();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,10 @@ using EFCore.BulkExtensions;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using ShardingCore;
|
using ShardingCore;
|
||||||
using ShardingCore.Bootstrappers;
|
|
||||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
|
||||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
|
||||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||||
using ShardingCore.Core.VirtualTables;
|
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
using ShardingCore.Sharding.Abstractions;
|
|
||||||
using ShardingCore.TableExists;
|
using ShardingCore.TableExists;
|
||||||
|
using ShardingCore.TableExists.Abstractions;
|
||||||
using ShardingCoreBenchmark5x.NoShardingDbContexts;
|
using ShardingCoreBenchmark5x.NoShardingDbContexts;
|
||||||
using ShardingCoreBenchmark5x.ShardingDbContexts;
|
using ShardingCoreBenchmark5x.ShardingDbContexts;
|
||||||
|
|
||||||
|
@ -25,10 +21,6 @@ namespace ShardingCoreBenchmark5x
|
||||||
{
|
{
|
||||||
private readonly DefaultDbContext _defaultDbContext;
|
private readonly DefaultDbContext _defaultDbContext;
|
||||||
private readonly DefaultShardingDbContext _defaultShardingDbContext;
|
private readonly DefaultShardingDbContext _defaultShardingDbContext;
|
||||||
private readonly IVirtualTableManager<DefaultShardingDbContext> _virtualTableManager;
|
|
||||||
private readonly IVirtualTable<Order> _virtualTable;
|
|
||||||
private readonly IRouteTailFactory _routeTailFactory;
|
|
||||||
private readonly IStreamMergeContextFactory<DefaultShardingDbContext> _streamMergeContextFactory;
|
|
||||||
public EFCoreCrud()
|
public EFCoreCrud()
|
||||||
{
|
{
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
|
@ -38,13 +30,10 @@ namespace ShardingCoreBenchmark5x
|
||||||
services.AddShardingDbContext<DefaultShardingDbContext>(ServiceLifetime.Transient, ServiceLifetime.Transient)
|
services.AddShardingDbContext<DefaultShardingDbContext>(ServiceLifetime.Transient, ServiceLifetime.Transient)
|
||||||
.AddEntityConfig(o =>
|
.AddEntityConfig(o =>
|
||||||
{
|
{
|
||||||
o.CreateShardingTableOnStart = true;
|
|
||||||
o.EnsureCreatedWithOutShardingTable = true;
|
|
||||||
o.AddShardingTableRoute<OrderVirtualTableRoute>();
|
o.AddShardingTableRoute<OrderVirtualTableRoute>();
|
||||||
})
|
})
|
||||||
.AddConfig(op =>
|
.AddConfig(op =>
|
||||||
{
|
{
|
||||||
op.ConfigId = "c1";
|
|
||||||
op.UseShardingQuery((conStr, builder) =>
|
op.UseShardingQuery((conStr, builder) =>
|
||||||
{
|
{
|
||||||
builder.UseSqlServer(conStr);
|
builder.UseSqlServer(conStr);
|
||||||
|
@ -53,14 +42,14 @@ namespace ShardingCoreBenchmark5x
|
||||||
{
|
{
|
||||||
builder.UseSqlServer(connection);
|
builder.UseSqlServer(connection);
|
||||||
});
|
});
|
||||||
op.ReplaceTableEnsureManager(sp => new SqlServerTableEnsureManager<DefaultShardingDbContext>());
|
|
||||||
op.AddDefaultDataSource("ds0",
|
op.AddDefaultDataSource("ds0",
|
||||||
"Data Source=localhost;Initial Catalog=db2;Integrated Security=True;");
|
"Data Source=localhost;Initial Catalog=db2;Integrated Security=True;");
|
||||||
|
|
||||||
}).EnsureConfig();
|
}).ReplaceService<ITableEnsureManager,SqlServerTableEnsureManager>().EnsureConfig();
|
||||||
|
|
||||||
var buildServiceProvider = services.BuildServiceProvider();
|
var buildServiceProvider = services.BuildServiceProvider();
|
||||||
buildServiceProvider.GetRequiredService<IShardingBootstrapper>().Start();
|
buildServiceProvider.UseAutoShardingCreate();
|
||||||
|
buildServiceProvider.UseAutoTryCompensateTable();
|
||||||
ICollection<Order> orders = new LinkedList<Order>();
|
ICollection<Order> orders = new LinkedList<Order>();
|
||||||
|
|
||||||
using (var scope = buildServiceProvider.CreateScope())
|
using (var scope = buildServiceProvider.CreateScope())
|
||||||
|
@ -111,17 +100,8 @@ namespace ShardingCoreBenchmark5x
|
||||||
Console.WriteLine($"批量插入订单数据:{orders.Count},用时:{sp.ElapsedMilliseconds}");
|
Console.WriteLine($"批量插入订单数据:{orders.Count},用时:{sp.ElapsedMilliseconds}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_defaultDbContext = ShardingContainer.GetService<DefaultDbContext>();
|
_defaultDbContext = buildServiceProvider.GetService<DefaultDbContext>();
|
||||||
_defaultShardingDbContext = ShardingContainer.GetService<DefaultShardingDbContext>();
|
_defaultShardingDbContext = buildServiceProvider.GetService<DefaultShardingDbContext>();
|
||||||
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<DefaultShardingDbContext>>();
|
|
||||||
_virtualTable = _virtualTableManager.GetVirtualTable<Order>();
|
|
||||||
_routeTailFactory= ShardingContainer.GetService<IRouteTailFactory>();
|
|
||||||
_streamMergeContextFactory =
|
|
||||||
ShardingContainer.GetService<IStreamMergeContextFactory<DefaultShardingDbContext>>();
|
|
||||||
var queryable1 = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == "0");
|
|
||||||
_virtualTable.RouteTo(new ShardingTableRouteConfig(queryable: queryable1));
|
|
||||||
var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == "1000");
|
|
||||||
_virtualTable.RouteTo(new ShardingTableRouteConfig(queryable: queryable));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,153 +1,153 @@
|
||||||
using System.Collections.Concurrent;
|
// using System.Collections.Concurrent;
|
||||||
using System.Linq.Expressions;
|
// using System.Linq.Expressions;
|
||||||
using MySqlConnector;
|
// using MySqlConnector;
|
||||||
using Newtonsoft.Json;
|
// using Newtonsoft.Json;
|
||||||
using ShardingCore.Core.EntityMetadatas;
|
// using ShardingCore.Core.EntityMetadatas;
|
||||||
using ShardingCore.Core.PhysicTables;
|
// using ShardingCore.Core.PhysicTables;
|
||||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
// using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
// using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||||
using ShardingCore.Core.VirtualRoutes;
|
// using ShardingCore.Core.VirtualRoutes;
|
||||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
// using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||||
using ShardingCore.Exceptions;
|
// using ShardingCore.Exceptions;
|
||||||
using ShardingCore.Extensions;
|
// using ShardingCore.Extensions;
|
||||||
using ShardingCore.TableCreator;
|
// using ShardingCore.TableCreator;
|
||||||
|
//
|
||||||
namespace Sample.AutoCreateIfPresent
|
// namespace Sample.AutoCreateIfPresent
|
||||||
{
|
// {
|
||||||
public class AreaDeviceRoute : AbstractShardingOperatorVirtualTableRoute<AreaDevice, string>
|
// public class AreaDeviceRoute : AbstractShardingOperatorVirtualTableRoute<AreaDevice, string>
|
||||||
{
|
// {
|
||||||
private const string Tables = "Tables";
|
// private const string Tables = "Tables";
|
||||||
private const string TABLE_SCHEMA = "TABLE_SCHEMA";
|
// private const string TABLE_SCHEMA = "TABLE_SCHEMA";
|
||||||
private const string TABLE_NAME = "TABLE_NAME";
|
// private const string TABLE_NAME = "TABLE_NAME";
|
||||||
|
//
|
||||||
private const string CurrentTableName = nameof(AreaDevice);
|
// private const string CurrentTableName = nameof(AreaDevice);
|
||||||
private readonly IVirtualDataSourceManager<DefaultDbContext> _virtualDataSourceManager;
|
// private readonly IVirtualDataSourceManager<DefaultDbContext> _virtualDataSourceManager;
|
||||||
private readonly IVirtualTableManager<DefaultDbContext> _virtualTableManager;
|
// private readonly IVirtualTableManager<DefaultDbContext> _virtualTableManager;
|
||||||
private readonly IShardingTableCreator<DefaultDbContext> _shardingTableCreator;
|
// private readonly IShardingTableCreator<DefaultDbContext> _shardingTableCreator;
|
||||||
private readonly ConcurrentDictionary<string, object?> _tails = new ConcurrentDictionary<string, object?>();
|
// private readonly ConcurrentDictionary<string, object?> _tails = new ConcurrentDictionary<string, object?>();
|
||||||
private readonly object _lock = new object();
|
// private readonly object _lock = new object();
|
||||||
|
//
|
||||||
public AreaDeviceRoute(IVirtualDataSourceManager<DefaultDbContext> virtualDataSourceManager, IVirtualTableManager<DefaultDbContext> virtualTableManager, IShardingTableCreator<DefaultDbContext> shardingTableCreator)
|
// public AreaDeviceRoute(IVirtualDataSourceManager<DefaultDbContext> virtualDataSourceManager, IVirtualTableManager<DefaultDbContext> virtualTableManager, IShardingTableCreator<DefaultDbContext> shardingTableCreator)
|
||||||
{
|
// {
|
||||||
_virtualDataSourceManager = virtualDataSourceManager;
|
// _virtualDataSourceManager = virtualDataSourceManager;
|
||||||
_virtualTableManager = virtualTableManager;
|
// _virtualTableManager = virtualTableManager;
|
||||||
_shardingTableCreator = shardingTableCreator;
|
// _shardingTableCreator = shardingTableCreator;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
public override string ShardingKeyToTail(object shardingKey)
|
// public override string ShardingKeyToTail(object shardingKey)
|
||||||
{
|
// {
|
||||||
return $"{shardingKey}";
|
// return $"{shardingKey}";
|
||||||
}
|
// }
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 如果你是非mysql数据库请自行实现这个方法返回当前类在数据库已经存在的后缀
|
// /// 如果你是非mysql数据库请自行实现这个方法返回当前类在数据库已经存在的后缀
|
||||||
/// 仅启动时调用
|
// /// 仅启动时调用
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <returns></returns>
|
// /// <returns></returns>
|
||||||
public override List<string> GetAllTails()
|
// public override List<string> GetAllTails()
|
||||||
{
|
// {
|
||||||
//启动寻找有哪些表后缀
|
// //启动寻找有哪些表后缀
|
||||||
using (var connection = new MySqlConnection(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultConnectionString))
|
// using (var connection = new MySqlConnection(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultConnectionString))
|
||||||
{
|
// {
|
||||||
connection.Open();
|
// connection.Open();
|
||||||
var database = connection.Database;
|
// var database = connection.Database;
|
||||||
|
//
|
||||||
using (var dataTable = connection.GetSchema(Tables))
|
// using (var dataTable = connection.GetSchema(Tables))
|
||||||
{
|
// {
|
||||||
for (int i = 0; i < dataTable.Rows.Count; i++)
|
// for (int i = 0; i < dataTable.Rows.Count; i++)
|
||||||
{
|
// {
|
||||||
var schema = dataTable.Rows[i][TABLE_SCHEMA];
|
// var schema = dataTable.Rows[i][TABLE_SCHEMA];
|
||||||
if (database.Equals($"{schema}", StringComparison.OrdinalIgnoreCase))
|
// if (database.Equals($"{schema}", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
// {
|
||||||
var tableName = dataTable.Rows[i][TABLE_NAME]?.ToString() ?? string.Empty;
|
// var tableName = dataTable.Rows[i][TABLE_NAME]?.ToString() ?? string.Empty;
|
||||||
if (tableName.StartsWith(CurrentTableName,StringComparison.OrdinalIgnoreCase))
|
// if (tableName.StartsWith(CurrentTableName,StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
// {
|
||||||
//如果没有下划线那么需要CurrentTableName.Length有下划线就要CurrentTableName.Length+1
|
// //如果没有下划线那么需要CurrentTableName.Length有下划线就要CurrentTableName.Length+1
|
||||||
_tails.TryAdd(tableName.Substring(CurrentTableName.Length+1), null);
|
// _tails.TryAdd(tableName.Substring(CurrentTableName.Length+1), null);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return _tails.Keys.ToList();
|
// return _tails.Keys.ToList();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public override void Configure(EntityMetadataTableBuilder<AreaDevice> builder)
|
// public override void Configure(EntityMetadataTableBuilder<AreaDevice> builder)
|
||||||
{
|
// {
|
||||||
builder.ShardingProperty(o => o.Area);
|
// builder.ShardingProperty(o => o.Area);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public override Func<string, bool> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
|
// public override Func<string, bool> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
|
||||||
{
|
// {
|
||||||
var t = ShardingKeyToTail(shardingKey);
|
// var t = ShardingKeyToTail(shardingKey);
|
||||||
switch (shardingOperator)
|
// switch (shardingOperator)
|
||||||
{
|
// {
|
||||||
case ShardingOperatorEnum.Equal: return tail => tail == t;
|
// case ShardingOperatorEnum.Equal: return tail => tail == t;
|
||||||
default:
|
// default:
|
||||||
{
|
// {
|
||||||
#if DEBUG
|
// #if DEBUG
|
||||||
Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
// Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
||||||
#endif
|
// #endif
|
||||||
return tail => true;
|
// return tail => true;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public override IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey)
|
// public override IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey)
|
||||||
{
|
// {
|
||||||
var shardingKeyToTail = ShardingKeyToTail(shardingKey);
|
// var shardingKeyToTail = ShardingKeyToTail(shardingKey);
|
||||||
|
//
|
||||||
if (!_tails.TryGetValue(shardingKeyToTail, out var _))
|
// if (!_tails.TryGetValue(shardingKeyToTail, out var _))
|
||||||
{
|
// {
|
||||||
lock (_lock)
|
// lock (_lock)
|
||||||
{
|
// {
|
||||||
if (!_tails.TryGetValue(shardingKeyToTail, out var _))
|
// if (!_tails.TryGetValue(shardingKeyToTail, out var _))
|
||||||
{
|
// {
|
||||||
var virtualTable = _virtualTableManager.GetVirtualTable(typeof(AreaDevice));
|
// var virtualTable = _virtualTableManager.GetVirtualTable(typeof(AreaDevice));
|
||||||
_virtualTableManager.AddPhysicTable(virtualTable, new DefaultPhysicTable(virtualTable, shardingKeyToTail));
|
// _virtualTableManager.AddPhysicTable(virtualTable, new DefaultPhysicTable(virtualTable, shardingKeyToTail));
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
_shardingTableCreator.CreateTable<AreaDevice>(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultDataSourceName, shardingKeyToTail);
|
// _shardingTableCreator.CreateTable<AreaDevice>(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultDataSourceName, shardingKeyToTail);
|
||||||
}
|
// }
|
||||||
catch (Exception ex)
|
// catch (Exception ex)
|
||||||
{
|
// {
|
||||||
Console.WriteLine("尝试添加表失败" + ex);
|
// Console.WriteLine("尝试添加表失败" + ex);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
_tails.TryAdd(shardingKeyToTail, null);
|
// _tails.TryAdd(shardingKeyToTail, null);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
var needRefresh = allPhysicTables.Count != _tails.Count;
|
// var needRefresh = allPhysicTables.Count != _tails.Count;
|
||||||
if (needRefresh)
|
// if (needRefresh)
|
||||||
{
|
// {
|
||||||
var virtualTable = _virtualTableManager.GetVirtualTable(typeof(AreaDevice));
|
// var virtualTable = _virtualTableManager.GetVirtualTable(typeof(AreaDevice));
|
||||||
//修复可能导致迭代器遍历时添加的bug
|
// //修复可能导致迭代器遍历时添加的bug
|
||||||
var keys = _tails.Keys.ToList();
|
// var keys = _tails.Keys.ToList();
|
||||||
foreach (var tail in keys)
|
// foreach (var tail in keys)
|
||||||
{
|
// {
|
||||||
var hashSet = allPhysicTables.Select(o => o.Tail).ToHashSet();
|
// var hashSet = allPhysicTables.Select(o => o.Tail).ToHashSet();
|
||||||
if (!hashSet.Contains(tail))
|
// if (!hashSet.Contains(tail))
|
||||||
{
|
// {
|
||||||
var tables = virtualTable.GetAllPhysicTables();
|
// var tables = virtualTable.GetAllPhysicTables();
|
||||||
var physicTable = tables.FirstOrDefault(o => o.Tail == tail);
|
// var physicTable = tables.FirstOrDefault(o => o.Tail == tail);
|
||||||
if (physicTable != null)
|
// if (physicTable != null)
|
||||||
{
|
// {
|
||||||
allPhysicTables.Add(physicTable);
|
// allPhysicTables.Add(physicTable);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
var physicTables = allPhysicTables.Where(o => o.Tail == shardingKeyToTail).ToList();
|
// var physicTables = allPhysicTables.Where(o => o.Tail == shardingKeyToTail).ToList();
|
||||||
if (physicTables.IsEmpty())
|
// 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))}]");
|
// 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)
|
// if (physicTables.Count > 1)
|
||||||
throw new ShardingCoreException($"more than one route match table:{string.Join(",", physicTables.Select(o => $"[{o.FullName}]"))}");
|
// throw new ShardingCoreException($"more than one route match table:{string.Join(",", physicTables.Select(o => $"[{o.FullName}]"))}");
|
||||||
return physicTables[0];
|
// return physicTables[0];
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
|
@ -1,184 +1,184 @@
|
||||||
using System;
|
// using System;
|
||||||
using System.Collections.Concurrent;
|
// using System.Collections.Concurrent;
|
||||||
using System.Linq.Expressions;
|
// using System.Linq.Expressions;
|
||||||
using MySqlConnector;
|
// using MySqlConnector;
|
||||||
using ShardingCore;
|
// using ShardingCore;
|
||||||
using ShardingCore.Core.EntityMetadatas;
|
// using ShardingCore.Core.EntityMetadatas;
|
||||||
using ShardingCore.Core.PhysicTables;
|
// using ShardingCore.Core.PhysicTables;
|
||||||
using ShardingCore.Core.ShardingConfigurations;
|
// using ShardingCore.Core.ShardingConfigurations;
|
||||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
// using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
// using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
// using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||||
using ShardingCore.Core.VirtualRoutes;
|
// using ShardingCore.Core.VirtualRoutes;
|
||||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
// using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||||
using ShardingCore.Exceptions;
|
// using ShardingCore.Exceptions;
|
||||||
using ShardingCore.Extensions;
|
// using ShardingCore.Extensions;
|
||||||
using ShardingCore.TableCreator;
|
// using ShardingCore.TableCreator;
|
||||||
using ShardingCore.TableExists;
|
// using ShardingCore.TableExists;
|
||||||
|
//
|
||||||
/*
|
// /*
|
||||||
* @Author: xjm
|
// * @Author: xjm
|
||||||
* @Description:
|
// * @Description:
|
||||||
* @Date: DATE
|
// * @Date: DATE
|
||||||
* @Email: 326308290@qq.com
|
// * @Email: 326308290@qq.com
|
||||||
*/
|
// */
|
||||||
namespace Sample.AutoCreateIfPresent
|
// namespace Sample.AutoCreateIfPresent
|
||||||
{
|
// {
|
||||||
public class OrderByHourRoute : AbstractShardingOperatorVirtualTableRoute<OrderByHour, DateTime>
|
// public class OrderByHourRoute : AbstractShardingOperatorVirtualTableRoute<OrderByHour, DateTime>
|
||||||
{
|
// {
|
||||||
private const string Tables = "Tables";
|
// private const string Tables = "Tables";
|
||||||
private const string TABLE_SCHEMA = "TABLE_SCHEMA";
|
// private const string TABLE_SCHEMA = "TABLE_SCHEMA";
|
||||||
private const string TABLE_NAME = "TABLE_NAME";
|
// private const string TABLE_NAME = "TABLE_NAME";
|
||||||
|
//
|
||||||
private const string CurrentTableName = nameof(OrderByHour);
|
// private const string CurrentTableName = nameof(OrderByHour);
|
||||||
private readonly IVirtualDataSourceManager<DefaultDbContext> _virtualDataSourceManager;
|
// private readonly IVirtualDataSourceManager<DefaultDbContext> _virtualDataSourceManager;
|
||||||
private readonly IVirtualTableManager<DefaultDbContext> _virtualTableManager;
|
// private readonly IVirtualTableManager<DefaultDbContext> _virtualTableManager;
|
||||||
private readonly IShardingTableCreator<DefaultDbContext> _shardingTableCreator;
|
// private readonly IShardingTableCreator<DefaultDbContext> _shardingTableCreator;
|
||||||
private readonly ConcurrentDictionary<string, object?> _tails = new ConcurrentDictionary<string, object?>();
|
// private readonly ConcurrentDictionary<string, object?> _tails = new ConcurrentDictionary<string, object?>();
|
||||||
private readonly object _lock = new object();
|
// private readonly object _lock = new object();
|
||||||
|
//
|
||||||
public OrderByHourRoute(IVirtualDataSourceManager<DefaultDbContext> virtualDataSourceManager,IVirtualTableManager<DefaultDbContext> virtualTableManager, IShardingTableCreator<DefaultDbContext> shardingTableCreator)
|
// public OrderByHourRoute(IVirtualDataSourceManager<DefaultDbContext> virtualDataSourceManager,IVirtualTableManager<DefaultDbContext> virtualTableManager, IShardingTableCreator<DefaultDbContext> shardingTableCreator)
|
||||||
{
|
// {
|
||||||
_virtualDataSourceManager = virtualDataSourceManager;
|
// _virtualDataSourceManager = virtualDataSourceManager;
|
||||||
_virtualTableManager = virtualTableManager;
|
// _virtualTableManager = virtualTableManager;
|
||||||
_shardingTableCreator = shardingTableCreator;
|
// _shardingTableCreator = shardingTableCreator;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public override string ShardingKeyToTail(object shardingKey)
|
// public override string ShardingKeyToTail(object shardingKey)
|
||||||
{
|
// {
|
||||||
var dateTime = (DateTime)shardingKey;
|
// var dateTime = (DateTime)shardingKey;
|
||||||
return ShardingKeyFormat(dateTime);
|
// return ShardingKeyFormat(dateTime);
|
||||||
}
|
// }
|
||||||
private string ShardingKeyFormat(DateTime dateTime)
|
// private string ShardingKeyFormat(DateTime dateTime)
|
||||||
{
|
// {
|
||||||
var tail = $"{dateTime:yyyyMMddHH}";
|
// var tail = $"{dateTime:yyyyMMddHH}";
|
||||||
|
//
|
||||||
return tail;
|
// return tail;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 如果你是非mysql数据库请自行实现这个方法返回当前类在数据库已经存在的后缀
|
// /// 如果你是非mysql数据库请自行实现这个方法返回当前类在数据库已经存在的后缀
|
||||||
/// 仅启动时调用
|
// /// 仅启动时调用
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
/// <returns></returns>
|
// /// <returns></returns>
|
||||||
public override List<string> GetTails()
|
// public override List<string> GetTails()
|
||||||
{
|
// {
|
||||||
//启动寻找有哪些表后缀
|
// //启动寻找有哪些表后缀
|
||||||
using (var connection = new MySqlConnection(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultConnectionString))
|
// using (var connection = new MySqlConnection(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultConnectionString))
|
||||||
{
|
// {
|
||||||
connection.Open();
|
// connection.Open();
|
||||||
var database = connection.Database;
|
// var database = connection.Database;
|
||||||
|
//
|
||||||
using (var dataTable = connection.GetSchema(Tables))
|
// using (var dataTable = connection.GetSchema(Tables))
|
||||||
{
|
// {
|
||||||
for (int i = 0; i < dataTable.Rows.Count; i++)
|
// for (int i = 0; i < dataTable.Rows.Count; i++)
|
||||||
{
|
// {
|
||||||
var schema = dataTable.Rows[i][TABLE_SCHEMA];
|
// var schema = dataTable.Rows[i][TABLE_SCHEMA];
|
||||||
if (database.Equals($"{schema}", StringComparison.OrdinalIgnoreCase))
|
// if (database.Equals($"{schema}", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
// {
|
||||||
var tableName = dataTable.Rows[i][TABLE_NAME]?.ToString()??string.Empty;
|
// var tableName = dataTable.Rows[i][TABLE_NAME]?.ToString()??string.Empty;
|
||||||
if (tableName.StartsWith(CurrentTableName, StringComparison.OrdinalIgnoreCase))
|
// if (tableName.StartsWith(CurrentTableName, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
// {
|
||||||
//如果没有下划线那么需要CurrentTableName.Length有下划线就要CurrentTableName.Length+1
|
// //如果没有下划线那么需要CurrentTableName.Length有下划线就要CurrentTableName.Length+1
|
||||||
_tails.TryAdd(tableName.Substring(CurrentTableName.Length+1),null);
|
// _tails.TryAdd(tableName.Substring(CurrentTableName.Length+1),null);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return _tails.Keys.ToList();
|
// return _tails.Keys.ToList();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public override void Configure(EntityMetadataTableBuilder<OrderByHour> builder)
|
// public override void Configure(EntityMetadataTableBuilder<OrderByHour> builder)
|
||||||
{
|
// {
|
||||||
builder.ShardingProperty(o => o.CreateTime);
|
// builder.ShardingProperty(o => o.CreateTime);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public override Func<string, bool> GetRouteToFilter(DateTime shardingKey, ShardingOperatorEnum shardingOperator)
|
// public override Func<string, bool> GetRouteToFilter(DateTime shardingKey, ShardingOperatorEnum shardingOperator)
|
||||||
{
|
// {
|
||||||
var t = ShardingKeyFormat(shardingKey);
|
// var t = ShardingKeyFormat(shardingKey);
|
||||||
switch (shardingOperator)
|
// switch (shardingOperator)
|
||||||
{
|
// {
|
||||||
case ShardingOperatorEnum.GreaterThan:
|
// case ShardingOperatorEnum.GreaterThan:
|
||||||
case ShardingOperatorEnum.GreaterThanOrEqual:
|
// case ShardingOperatorEnum.GreaterThanOrEqual:
|
||||||
return tail => String.Compare(tail, t, StringComparison.Ordinal) >= 0;
|
// return tail => String.Compare(tail, t, StringComparison.Ordinal) >= 0;
|
||||||
case ShardingOperatorEnum.LessThan:
|
// case ShardingOperatorEnum.LessThan:
|
||||||
{
|
// {
|
||||||
var currentHourBeginTime = new DateTime(shardingKey.Year,shardingKey.Month,shardingKey.Day,shardingKey.Hour,0,0);
|
// var currentHourBeginTime = new DateTime(shardingKey.Year,shardingKey.Month,shardingKey.Day,shardingKey.Hour,0,0);
|
||||||
//处于临界值 o=>o.time < [2021-01-01 00:00:00] 尾巴20210101不应该被返回
|
// //处于临界值 o=>o.time < [2021-01-01 00:00:00] 尾巴20210101不应该被返回
|
||||||
if (currentHourBeginTime == shardingKey)
|
// if (currentHourBeginTime == shardingKey)
|
||||||
return tail => String.Compare(tail, t, StringComparison.Ordinal) < 0;
|
// return tail => String.Compare(tail, t, StringComparison.Ordinal) < 0;
|
||||||
return tail => String.Compare(tail, t, StringComparison.Ordinal) <= 0;
|
// return tail => String.Compare(tail, t, StringComparison.Ordinal) <= 0;
|
||||||
}
|
// }
|
||||||
case ShardingOperatorEnum.LessThanOrEqual:
|
// case ShardingOperatorEnum.LessThanOrEqual:
|
||||||
return tail => String.Compare(tail, t, StringComparison.Ordinal) <= 0;
|
// return tail => String.Compare(tail, t, StringComparison.Ordinal) <= 0;
|
||||||
case ShardingOperatorEnum.Equal: return tail => tail == t;
|
// case ShardingOperatorEnum.Equal: return tail => tail == t;
|
||||||
default:
|
// default:
|
||||||
{
|
// {
|
||||||
#if DEBUG
|
// #if DEBUG
|
||||||
Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
// Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
||||||
#endif
|
// #endif
|
||||||
return tail => true;
|
// return tail => true;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public override IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey)
|
// public override IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey)
|
||||||
{
|
// {
|
||||||
var shardingKeyToTail = ShardingKeyToTail(shardingKey);
|
// var shardingKeyToTail = ShardingKeyToTail(shardingKey);
|
||||||
|
//
|
||||||
if (!_tails.TryGetValue(shardingKeyToTail,out var _))
|
// if (!_tails.TryGetValue(shardingKeyToTail,out var _))
|
||||||
{
|
// {
|
||||||
lock (_lock)
|
// lock (_lock)
|
||||||
{
|
// {
|
||||||
if (!_tails.TryGetValue(shardingKeyToTail,out var _))
|
// if (!_tails.TryGetValue(shardingKeyToTail,out var _))
|
||||||
{
|
// {
|
||||||
var virtualTable = _virtualTableManager.GetVirtualTable(typeof(OrderByHour));
|
// var virtualTable = _virtualTableManager.GetVirtualTable(typeof(OrderByHour));
|
||||||
//必须先执行AddPhysicTable在进行CreateTable
|
// //必须先执行AddPhysicTable在进行CreateTable
|
||||||
_virtualTableManager.AddPhysicTable(virtualTable, new DefaultPhysicTable(virtualTable, shardingKeyToTail));
|
// _virtualTableManager.AddPhysicTable(virtualTable, new DefaultPhysicTable(virtualTable, shardingKeyToTail));
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
_shardingTableCreator.CreateTable<OrderByHour>(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultDataSourceName, shardingKeyToTail);
|
// _shardingTableCreator.CreateTable<OrderByHour>(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultDataSourceName, shardingKeyToTail);
|
||||||
}
|
// }
|
||||||
catch (Exception ex)
|
// catch (Exception ex)
|
||||||
{
|
// {
|
||||||
Console.WriteLine("尝试添加表失败" + ex);
|
// Console.WriteLine("尝试添加表失败" + ex);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
_tails.TryAdd(shardingKeyToTail,null);
|
// _tails.TryAdd(shardingKeyToTail,null);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
var needRefresh = allPhysicTables.Count != _tails.Count;
|
// var needRefresh = allPhysicTables.Count != _tails.Count;
|
||||||
if (needRefresh)
|
// if (needRefresh)
|
||||||
{
|
// {
|
||||||
var virtualTable = _virtualTableManager.GetVirtualTable(typeof(OrderByHour));
|
// var virtualTable = _virtualTableManager.GetVirtualTable(typeof(OrderByHour));
|
||||||
//修复可能导致迭代器遍历时添加的bug
|
// //修复可能导致迭代器遍历时添加的bug
|
||||||
var keys = _tails.Keys.ToList();
|
// var keys = _tails.Keys.ToList();
|
||||||
foreach (var tail in keys)
|
// foreach (var tail in keys)
|
||||||
{
|
// {
|
||||||
var hashSet = allPhysicTables.Select(o=>o.Tail).ToHashSet();
|
// var hashSet = allPhysicTables.Select(o=>o.Tail).ToHashSet();
|
||||||
if (!hashSet.Contains(tail))
|
// if (!hashSet.Contains(tail))
|
||||||
{
|
// {
|
||||||
var tables = virtualTable.GetAllPhysicTables();
|
// var tables = virtualTable.GetAllPhysicTables();
|
||||||
var physicTable = tables.FirstOrDefault(o=>o.Tail==tail);
|
// var physicTable = tables.FirstOrDefault(o=>o.Tail==tail);
|
||||||
if (physicTable!= null)
|
// if (physicTable!= null)
|
||||||
{
|
// {
|
||||||
allPhysicTables.Add(physicTable);
|
// allPhysicTables.Add(physicTable);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
var physicTables = allPhysicTables.Where(o => o.Tail== shardingKeyToTail).ToList();
|
// var physicTables = allPhysicTables.Where(o => o.Tail== shardingKeyToTail).ToList();
|
||||||
if (physicTables.IsEmpty())
|
// 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))}]");
|
// 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)
|
// if (physicTables.Count > 1)
|
||||||
throw new ShardingCoreException($"more than one route match table:{string.Join(",", physicTables.Select(o => $"[{o.FullName}]"))}");
|
// throw new ShardingCoreException($"more than one route match table:{string.Join(",", physicTables.Select(o => $"[{o.FullName}]"))}");
|
||||||
return physicTables[0];
|
// return physicTables[0];
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
|
@ -22,8 +22,8 @@ builder.Services.AddShardingDbContext<DefaultDbContext>()
|
||||||
.AddEntityConfig(o =>
|
.AddEntityConfig(o =>
|
||||||
{
|
{
|
||||||
o.ThrowIfQueryRouteNotMatch = false;
|
o.ThrowIfQueryRouteNotMatch = false;
|
||||||
o.AddShardingTableRoute<OrderByHourRoute>();
|
// o.AddShardingTableRoute<OrderByHourRoute>();
|
||||||
o.AddShardingTableRoute<AreaDeviceRoute>();
|
// o.AddShardingTableRoute<AreaDeviceRoute>();
|
||||||
})
|
})
|
||||||
.AddConfig(o =>
|
.AddConfig(o =>
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue