Split table

This commit is contained in:
sunkaixuna
2021-10-29 11:44:08 +08:00
parent 35163aa1c1
commit 5d6f2dda5a
15 changed files with 266 additions and 113 deletions

View File

@@ -46,12 +46,13 @@ namespace OrmTest
.ExecuteCommand();
//按日分表
var x3 = db.Insertable(new OrderSpliteTest() { Name="A" }).SplitTable(SplitType.Day).ExecuteCommand();
//按日分表根据time字段扔到对应的表中
var x4 = db.Insertable(new OrderSpliteTest() { Name = "A" }).SplitTable(SplitType.Day,it=>it.Time).ExecuteCommand();
var x3 = db.Insertable(new OrderSpliteTest() { Name="A" }).SplitTable().ExecuteCommand();
////强制分表类型
//var x4 = db.Insertable(new OrderSpliteTest() { Name = "A" }).SplitTable(SplitType.Day).ExecuteCommand();
Console.WriteLine("#### CodeFirst end ####");
}
[SplitTable(SplitType.Day)]
[SqlSugar.SugarTable("Taxxx0101_{year}{month}{day}")]
public class OrderSpliteTest
{
@@ -59,6 +60,7 @@ namespace OrmTest
public Guid Pk{ get; set; }
public string Name { get; set; }
[SugarColumn(IsNullable =true)]
[SplitField]
public DateTime Time { get; set; }
}
}

View File

@@ -12,7 +12,7 @@ namespace SqlSugar
public void InitTables<T>()
{
//var oldMapping = this.Context.Utilities.TranslateCopy(this.Context.MappingTables);
SplitTableHelper helper = new SplitTableHelper()
SplitTableContext helper = new SplitTableContext()
{
Context = this.Context,
EntityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>()

View File

@@ -263,7 +263,7 @@ namespace SqlSugar
this.Context.MappingTables.Add(this.EntityInfo.EntityName, this.EntityInfo.DbTableName);
SplitTableDeleteProvider<T> result = new SplitTableDeleteProvider<T>();
result.Context = this.Context;
SplitTableHelper helper = new SplitTableHelper()
SplitTableContext helper = new SplitTableContext()
{
Context =(SqlSugarProvider)Context,
EntityInfo = this.EntityInfo

View File

@@ -408,59 +408,30 @@ namespace SqlSugar
}
public SplitInsertable<T> SplitTable(SplitType splitType)
{
SplitTableHelper helper = new SplitTableHelper()
SplitTableContext helper = new SplitTableContext()
{
Context = this.Context,
EntityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>()
};
helper.CheckPrimaryKey();
var table=helper.GetTableNameByDate(helper.GetTableGetDate(this.Context.GetDate(),splitType));
SplitInsertable<T> result = new SplitInsertable<T>();
result.Context = this.Context;
result.EntityInfo = this.EntityInfo;
result.TableNames = new List<string>() { table};
result.TableNames = new List<string>();
foreach (var item in this.InsertObjs)
{
var splitFieldValue = helper.GetValue(splitType, item);
var tableName=helper.GetTableName(splitType, splitFieldValue);
result.TableNames.Add(tableName);
}
result.Inserable = this;
return result;
}
public SplitInsertable<T> SplitTable(SplitType splitType, Expression<Func<T, DateTime>> splitFieldName)
public SplitInsertable<T> SplitTable()
{
SplitTableHelper helper = new SplitTableHelper()
{
Context = this.Context,
EntityInfo = this.Context.EntityMaintenance.GetEntityInfo<T>()
};
helper.CheckPrimaryKey();
SplitInsertable<T> result = new SplitInsertable<T>();
result.Context = this.Context;
result.EntityInfo = this.EntityInfo;
result.TableNames = new List<string>();
List<DateTime> times = new List<DateTime>();
foreach (var item in times)
{
result.TableNames.Add(helper.GetTableNameByDate(helper.GetTableGetDate(item, splitType)));
}
return result;
}
public SplitInsertable<T> SplitTable(SplitType splitType, Expression<Func<T, DateTime?>> splitFieldName)
{
SplitTableHelper helper = new SplitTableHelper()
{
Context=this.Context,
EntityInfo=this.Context.EntityMaintenance.GetEntityInfo<T>()
};
helper.CheckPrimaryKey();
SplitInsertable<T> result = new SplitInsertable<T>();
result.Context = this.Context;
result.EntityInfo = this.EntityInfo;
result.TableNames = new List<string>();
List<DateTime> times = new List<DateTime>();
foreach (var item in times)
{
result.TableNames.Add(helper.GetTableNameByDate(helper.GetTableGetDate(item, splitType)));
}
return result;
SplitType SplitType = SplitType.Day;
return SplitTable(SplitType);
}
#endregion

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar
{
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class SplitTableAttribute : Attribute
{
public SplitType SplitType { get; set; }
public SplitTableAttribute(SplitType splitType)
{
this.SplitType = splitType;
}
}
[AttributeUsage(AttributeTargets.Property, Inherited = true)]
public class SplitFieldAttribute : Attribute
{
public SplitFieldAttribute()
{
}
}
}

View File

@@ -94,7 +94,7 @@ namespace SqlSugar
this.Context.MappingTables.Add(this.EntityInfo.EntityName, this.EntityInfo.DbTableName);
SplitTableUpdateProvider<T> result = new SplitTableUpdateProvider<T>();
result.Context = this.Context;
SplitTableHelper helper = new SplitTableHelper()
SplitTableContext helper = new SplitTableContext()
{
Context = (SqlSugarProvider)Context,
EntityInfo = this.EntityInfo

View File

@@ -79,7 +79,7 @@ namespace SqlSugar
private ICacheService _ReflectionInoCache;
private ICacheService _DataInfoCache;
private IRazorService _RazorService;
public ISplitTableService SplitTableService { get; set; }
public IRazorService RazorService
{
get

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar
{
public interface ISplitTableService
{
List<SplitTableInfo> GetAllTables(ISqlSugarClient db,EntityInfo EntityInfo,List<DbTableInfo> tableInfos);
string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo);
string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo, SplitType type);
string GetTableName(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object fieldValue);
object GetFieldValue(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object entityValue);
}
}

View File

@@ -1,59 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace SqlSugar
{
internal class SplitTableHelper
public class DateSplitTableService : ISplitTableService
{
public SqlSugarProvider Context { get; set; }
public EntityInfo EntityInfo { get; set; }
#region Common Method
public DateTime GetTableGetDate(DateTime time, SplitType type)
public List<SplitTableInfo> GetAllTables(ISqlSugarClient db, EntityInfo EntityInfo,List<DbTableInfo> tableInfos)
{
switch (type)
{
case SplitType.Day:
return Convert.ToDateTime(time.ToString("yyyy-MM-dd"));
case SplitType.Week:
return GetMondayDate(time);
case SplitType.Month:
return Convert.ToDateTime(time.ToString("yyyy-MM-01"));
case SplitType.Season:
if (time.Month <= 3)
{
return Convert.ToDateTime(time.ToString("yyyy-01-01"));
}
else if (time.Month <= 6)
{
return Convert.ToDateTime(time.ToString("yyyy-04-01"));
}
else if (time.Month <= 9)
{
return Convert.ToDateTime(time.ToString("yyyy-07-01"));
}
else
{
return Convert.ToDateTime(time.ToString("yyyy-10-01"));
}
case SplitType.Year:
return Convert.ToDateTime(time.ToString("yyyy-01-01"));
default:
throw new Exception($"SplitType paramter error ");
}
}
public List<SplitTableInfo> GetTables()
{
var oldIsEnableLogEvent = this.Context.Ado.IsEnableLogEvent;
this.Context.Ado.IsEnableLogEvent = false;
var tableInfos = this.Context.DbMaintenance.GetTableInfoList(false);
SplitTableHelper.CheckTableName(EntityInfo.DbTableName);
CheckTableName(EntityInfo.DbTableName);
var regex = EntityInfo.DbTableName.Replace("{year}", "([0-9]{2,4})").Replace("{day}", "([0-9]{1,2})").Replace("{month}", "([0-9]{1,2})");
var currentTables = tableInfos.Where(it => Regex.IsMatch(it.Name, regex, RegexOptions.IgnoreCase)).Select(it => it.Name).Reverse().ToList();
List<SplitTableInfo> result = new List<SplitTableInfo>();
@@ -66,29 +25,84 @@ namespace SqlSugar
var group2 = math.Groups[2].Value;
var group3 = math.Groups[3].Value;
tableInfo.Date = GetDate(group1, group2, group3, EntityInfo.DbTableName);
//tableInfo.String = null; Time table, it doesn't work
//tableInfo.Long = null; Time table, it doesn't work
result.Add(tableInfo);
}
result = result.OrderByDescending(it => it.Date).ToList();
this.Context.Ado.IsEnableLogEvent = oldIsEnableLogEvent;
return result;
}
public string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo)
{
return GetTableName(db,EntityInfo,SplitType.Day);
}
public string GetDefaultTableName()
public string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo,SplitType splitType)
{
var date = this.Context.GetDate();
return GetTableNameByDate(date);
var date =db.GetDate();
return GetTableNameByDate(EntityInfo,splitType,date);
}
public string GetTableNameByDate(DateTime date)
public string GetTableName(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object fieldValue)
{
return EntityInfo.DbTableName.Replace("{year}", date.Year + "").Replace("{day}", PadLeft2(date.Day + "")).Replace("{month}", PadLeft2(date.Month + ""));
var value= Convert.ToDateTime(fieldValue);
return GetTableNameByDate(entityInfo,splitType, value);
}
public void CheckPrimaryKey()
public object GetFieldValue(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object entityValue)
{
Check.Exception(EntityInfo.Columns.Any(it => it.IsIdentity == true), ErrorMessage.GetThrowMessage("Split table can't IsIdentity=true", "分表禁止使用自增列"));
var splitColumn=entityInfo.Columns.FirstOrDefault(it => it.PropertyInfo.PropertyType.GetCustomAttribute<SplitFieldAttribute>()!=null);
if (splitColumn == null)
{
return db.GetDate();
}
else
{
var value= splitColumn.PropertyInfo.GetValue(entityValue, null);
if (value == null)
{
return db.GetDate();
}
else if (UtilMethods.GetUnderType(value.GetType()) != UtilConstants.DateType)
{
throw new Exception($"DateSplitTableService Split column {splitColumn.PropertyName} not DateTime " + splitType.ToString());
}
else if (Convert.ToDateTime(value) == DateTime.MinValue)
{
return db.GetDate();
}
else
{
return value;
}
}
}
public void VerifySplitType(SplitType splitType)
{
switch (splitType)
{
case SplitType.Day:
break;
case SplitType.Week:
break;
case SplitType.Month:
break;
case SplitType.Season:
break;
case SplitType.Year:
break;
default:
throw new Exception("DateSplitTableService no support "+ splitType.ToString());
}
}
#endregion
#region Common Helper
private string GetTableNameByDate(EntityInfo EntityInfo,SplitType splitType,DateTime date)
{
date = ConvertDateBySplitType(date, splitType);
return EntityInfo.DbTableName.Replace("{year}", date.Year + "").Replace("{day}", PadLeft2(date.Day + "")).Replace("{month}", PadLeft2(date.Month + ""));
}
private DateTime GetDate(string group1, string group2, string group3, string dbTableName)
{
var yearIndex = dbTableName.IndexOf("{year}");
@@ -166,6 +180,39 @@ namespace SqlSugar
#endregion
#region Date Helper
private DateTime ConvertDateBySplitType(DateTime time, SplitType type)
{
switch (type)
{
case SplitType.Day:
return Convert.ToDateTime(time.ToString("yyyy-MM-dd"));
case SplitType.Week:
return GetMondayDate(time);
case SplitType.Month:
return Convert.ToDateTime(time.ToString("yyyy-MM-01"));
case SplitType.Season:
if (time.Month <= 3)
{
return Convert.ToDateTime(time.ToString("yyyy-01-01"));
}
else if (time.Month <= 6)
{
return Convert.ToDateTime(time.ToString("yyyy-04-01"));
}
else if (time.Month <= 9)
{
return Convert.ToDateTime(time.ToString("yyyy-07-01"));
}
else
{
return Convert.ToDateTime(time.ToString("yyyy-10-01"));
}
case SplitType.Year:
return Convert.ToDateTime(time.ToString("yyyy-01-01"));
default:
throw new Exception($"SplitType paramter error ");
}
}
private DateTime GetMondayDate()
{
return GetMondayDate(DateTime.Now);
@@ -188,6 +235,7 @@ namespace SqlSugar
TimeSpan ts = new TimeSpan(i, 0, 0, 0);
return someDate.Add(ts);
}
#endregion
}
}

View File

@@ -46,10 +46,8 @@ namespace SqlSugar
MySqlBlukCopy<T> UseMySql();
OracleBlukCopy UseOracle();
SplitInsertable<T> SplitTable();
SplitInsertable<T> SplitTable(SplitType splitType);
SplitInsertable<T> SplitTable(SplitType splitType,Expression<Func<T,DateTime>> splitFieldName);
SplitInsertable<T> SplitTable(SplitType splitType, Expression<Func<T, DateTime?>> splitFieldName);
void AddQueue();
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace SqlSugar
{
internal class SplitTableContext
{
public SqlSugarProvider Context { get; set; }
public EntityInfo EntityInfo { get; set; }
public ISplitTableService Service { get; set; }
public SplitTableContext()
{
if (this.Context.CurrentConnectionConfig.ConfigureExternalServices != null&&this.Context.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService!=null)
{
Service = this.Context.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService;
}
else
{
Service = new DateSplitTableService();
}
}
public List<SplitTableInfo> GetTables()
{
var oldIsEnableLogEvent = this.Context.Ado.IsEnableLogEvent;
this.Context.Ado.IsEnableLogEvent = false;
var tableInfos = this.Context.DbMaintenance.GetTableInfoList(false);
List<SplitTableInfo> result = Service.GetAllTables(this.Context,EntityInfo,tableInfos);
this.Context.Ado.IsEnableLogEvent = oldIsEnableLogEvent;
return result;
}
internal string GetDefaultTableName()
{
return Service.GetTableName(this.Context,EntityInfo);
}
internal string GetTableName(SplitType splitType)
{
return Service.GetTableName(this.Context,EntityInfo, splitType);
}
internal string GetTableName(SplitType splitType, object fieldValue)
{
return Service.GetTableName(this.Context,EntityInfo, splitType, fieldValue);
}
internal object GetValue(SplitType splitType, object entityValue)
{
return Service.GetFieldValue(this.Context,EntityInfo, splitType, entityValue);
}
public void CheckPrimaryKey()
{
Check.Exception(EntityInfo.Columns.Any(it => it.IsIdentity == true), ErrorMessage.GetThrowMessage("Split table can't IsIdentity=true", "分表禁止使用自增列"));
}
}
}

View File

@@ -10,6 +10,11 @@ namespace SqlSugar
{
public string TableName { get; set; }
public DateTime Date { get; set; }
public String String { get; set; }
public decimal Decimal { get; set; }
public long Long { get; set; }
public int Int { get; set; }
public Byte[] ByteArray { get; set; }
}
internal class SplitTableSort

View File

@@ -12,6 +12,12 @@ namespace SqlSugar
Week = 1,
Month = 2,
Season = 3,
Year=4
Year = 4,
_Custom01 = 5,
_Custom02 = 6,
_Custom03 = 7,
_Custom04 = 8,
_Custom05 = 9,
_Custom06 = 10,
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SqlSugar
{
public static class SplitTypeExtensions
{
}
}

View File

@@ -88,6 +88,7 @@
<Compile Include="Abstract\EntityMaintenance\EntityMaintenance.cs" />
<Compile Include="Abstract\ExpressionableProvider\Expressionable.cs" />
<Compile Include="Abstract\FilterProvider\FilterProvider.cs" />
<Compile Include="Abstract\InsertableProvider\SplitTableAttribute.cs" />
<Compile Include="Abstract\InsertableProvider\InsertableProvider.cs" />
<Compile Include="Abstract\DeleteProvider\DeleteableProvider.cs" />
<Compile Include="Abstract\InsertableProvider\SplitInsertable.cs" />
@@ -213,9 +214,12 @@
<Compile Include="DistributedSystem\Snowflake\IdWorker.cs" />
<Compile Include="DistributedSystem\Snowflake\InvalidSystemClock.cs" />
<Compile Include="DistributedSystem\Snowflake\TimeExtensions.cs" />
<Compile Include="SpliteTable\SplitHelper.cs" />
<Compile Include="IntegrationServices\SplitTableService.cs" />
<Compile Include="ExternalServiceInterface\ISplitTableService.cs" />
<Compile Include="SpliteTable\SplitTableContext.cs" />
<Compile Include="SpliteTable\SplitTableInfo.cs" />
<Compile Include="SpliteTable\SplitType.cs" />
<Compile Include="SpliteTable\SplitTypeExtensions.cs" />
<Compile Include="SqlSugarClient.cs" />
<Compile Include="Utilities\CallContext.cs" />
<Compile Include="Utilities\CallContextAsync.cs" />