diff --git a/ShardingCore.sln b/ShardingCore.sln index ebedb93f..86c27b97 100644 --- a/ShardingCore.sln +++ b/ShardingCore.sln @@ -79,6 +79,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore7", "src7\Shard EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src7", "src7", "{A5321A3E-8539-4E2A-889C-8E91989EECBD}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShardingCore.Test7x", "src\ShardingCore.Test7x\ShardingCore.Test7x.csproj", "{FC6C1017-69D5-44E0-8C4C-99B6F476FB55}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -201,6 +203,10 @@ Global {A308D253-A072-40EC-AA97-15EE82BB8AAD}.Debug|Any CPU.Build.0 = Debug|Any CPU {A308D253-A072-40EC-AA97-15EE82BB8AAD}.Release|Any CPU.ActiveCfg = Release|Any CPU {A308D253-A072-40EC-AA97-15EE82BB8AAD}.Release|Any CPU.Build.0 = Release|Any CPU + {FC6C1017-69D5-44E0-8C4C-99B6F476FB55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC6C1017-69D5-44E0-8C4C-99B6F476FB55}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC6C1017-69D5-44E0-8C4C-99B6F476FB55}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC6C1017-69D5-44E0-8C4C-99B6F476FB55}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -235,6 +241,7 @@ Global {F0393C32-2285-4F47-AC61-C1BA1CAC269D} = {B11D7DF7-A907-407E-8BF1-35B430413557} {3B5A4B03-5190-41A8-8E4B-F95A79A5C018} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73} {A308D253-A072-40EC-AA97-15EE82BB8AAD} = {A5321A3E-8539-4E2A-889C-8E91989EECBD} + {FC6C1017-69D5-44E0-8C4C-99B6F476FB55} = {CC2C88C0-65F2-445D-BE78-973B840FE281} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8C07A667-E8B4-43C7-8053-721584BAD291} diff --git a/nuget-publish.bat b/nuget-publish.bat index 2da1f2af..55e69b01 100644 --- a/nuget-publish.bat +++ b/nuget-publish.bat @@ -1,11 +1,11 @@ :start ::定义版本 -set EFCORE8=7.8.1.19 -set EFCORE7=7.7.1.19 -set EFCORE6=7.6.1.19 -set EFCORE5=7.5.1.19 -set EFCORE3=7.3.1.19 -set EFCORE2=7.2.1.19 +set EFCORE8=7.8.1.19-preview1 +set EFCORE7=7.7.1.19-preview1 +set EFCORE6=7.6.1.19-preview1 +set EFCORE5=7.5.1.19-preview1 +set EFCORE3=7.3.1.19-preview1 +set EFCORE2=7.2.1.19-preview1 ::删除所有bin与obj下的文件 @echo off diff --git a/samples/Sample.SqlServer/Sample.SqlServer.csproj b/samples/Sample.SqlServer/Sample.SqlServer.csproj index 8cdf1b55..06f2338d 100644 --- a/samples/Sample.SqlServer/Sample.SqlServer.csproj +++ b/samples/Sample.SqlServer/Sample.SqlServer.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/ShardingCore.Test7x/Common/SnowflakeId.cs b/src/ShardingCore.Test7x/Common/SnowflakeId.cs new file mode 100644 index 00000000..b8d6337d --- /dev/null +++ b/src/ShardingCore.Test7x/Common/SnowflakeId.cs @@ -0,0 +1,196 @@ +using System; +using System.Text; + +namespace ShardingCore.Test.Common +{/// + /// 雪花ID + /// Twitter_Snowflake + /// SnowFlake的结构如下(每部分用-分开) + /// 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 + /// 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0 + /// 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)得到的值), + /// 41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69 + /// 这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。 + /// 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId + /// 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号 + /// 总共加起来刚好64位,为一个Long型。 + /// SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分), + /// 并且效率较高,经测试,SnowFlake单机每秒都能够产生出极限4,096,000个ID来 + /// + public class SnowflakeId + { + + // 开始时间截 (new DateTime(2020, 1, 1).ToUniversalTime() - Jan1st1970).TotalMilliseconds + private const long twepoch = 1577808000000L; + + // 机器id所占的位数 + private const int workerIdBits = 5; + + // 数据标识id所占的位数 + private const int datacenterIdBits = 5; + + // 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) + private const long maxWorkerId = -1L ^ (-1L << workerIdBits); + + // 支持的最大数据标识id,结果是31 + private const long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); + + // 序列在id中占的位数 + private const int sequenceBits = 12; + + // 数据标识id向左移17位(12+5) + private const int datacenterIdShift = sequenceBits + workerIdBits; + + // 机器ID向左移12位 + private const int workerIdShift = sequenceBits; + + + // 时间截向左移22位(5+5+12) + private const int timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; + + // 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) + private const long sequenceMask = -1L ^ (-1L << sequenceBits); + + // 数据中心ID(0~31) + public long datacenterId { get; private set; } + + // 工作机器ID(0~31) + public long workerId { get; private set; } + + // 毫秒内序列(0~4095) + public long sequence { get; private set; } + + // 上次生成ID的时间截 + public long lastTimestamp { get; private set; } + + + /// + /// 雪花ID + /// + /// 数据中心ID + /// 工作机器ID + public SnowflakeId(long datacenterId, long workerId) + { + if (datacenterId > maxDatacenterId || datacenterId < 0) + { + throw new Exception(string.Format("datacenter Id can't be greater than {0} or less than 0", maxDatacenterId)); + } + if (workerId > maxWorkerId || workerId < 0) + { + throw new Exception(string.Format("worker Id can't be greater than {0} or less than 0", maxWorkerId)); + } + this.workerId = workerId; + this.datacenterId = datacenterId; + this.sequence = 0L; + this.lastTimestamp = -1L; + } + + /// + /// 获得下一个ID + /// + /// + public long NextId() + { + lock (this) + { + long timestamp = GetCurrentTimestamp(); + if (timestamp > lastTimestamp) //时间戳改变,毫秒内序列重置 + { + sequence = 0L; + } + else if (timestamp == lastTimestamp) //如果是同一时间生成的,则进行毫秒内序列 + { + sequence = (sequence + 1) & sequenceMask; + if (sequence == 0) //毫秒内序列溢出 + { + timestamp = GetNextTimestamp(lastTimestamp); //阻塞到下一个毫秒,获得新的时间戳 + } + } + else //当前时间小于上一次ID生成的时间戳,证明系统时钟被回拨,此时需要做回拨处理 + { + sequence = (sequence + 1) & sequenceMask; + if (sequence > 0) + { + timestamp = lastTimestamp; //停留在最后一次时间戳上,等待系统时间追上后即完全度过了时钟回拨问题。 + } + else //毫秒内序列溢出 + { + timestamp = lastTimestamp + 1; //直接进位到下一个毫秒 + } + //throw new Exception(string.Format("Clock moved backwards. Refusing to generate id for {0} milliseconds", lastTimestamp - timestamp)); + } + + lastTimestamp = timestamp; //上次生成ID的时间截 + + //移位并通过或运算拼到一起组成64位的ID + var id = ((timestamp - twepoch) << timestampLeftShift) + | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) + | sequence; + return id; + } + } + + /// + /// 解析雪花ID + /// + /// + public static DateTime AnalyzeIdToDateTime(long Id) + { + + var timestamp = (Id >> timestampLeftShift); + var time = Jan1st1970.AddMilliseconds(timestamp + twepoch); + return time.ToLocalTime(); + } + + /// + /// 解析雪花ID + /// + /// + public static string AnalyzeId(long Id) + { + StringBuilder sb = new StringBuilder(); + + var timestamp = (Id >> timestampLeftShift); + var time = Jan1st1970.AddMilliseconds(timestamp + twepoch); + sb.Append(time.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss:fff")); + + var datacenterId = (Id ^ (timestamp << timestampLeftShift)) >> datacenterIdShift; + sb.Append("_" + datacenterId); + + var workerId = (Id ^ ((timestamp << timestampLeftShift) | (datacenterId << datacenterIdShift))) >> workerIdShift; + sb.Append("_" + workerId); + + var sequence = Id & sequenceMask; + sb.Append("_" + sequence); + + return sb.ToString(); + } + + /// + /// 阻塞到下一个毫秒,直到获得新的时间戳 + /// + /// 上次生成ID的时间截 + /// 当前时间戳 + private static long GetNextTimestamp(long lastTimestamp) + { + long timestamp = GetCurrentTimestamp(); + while (timestamp <= lastTimestamp) + { + timestamp = GetCurrentTimestamp(); + } + return timestamp; + } + + /// + /// 获取当前时间戳 + /// + /// + private static long GetCurrentTimestamp() + { + return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds; + } + + private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + } +} diff --git a/src/ShardingCore.Test7x/Domain/Entities/LogDay.cs b/src/ShardingCore.Test7x/Domain/Entities/LogDay.cs new file mode 100644 index 00000000..cec94311 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/LogDay.cs @@ -0,0 +1,12 @@ +using System; + +namespace ShardingCore.Test.Domain.Entities +{ + public class LogDay + { + public Guid Id { get; set; } + public string LogLevel { get; set; } + public string LogBody { get; set; } + public DateTime LogTime { get; set; } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Entities/LogDayLong.cs b/src/ShardingCore.Test7x/Domain/Entities/LogDayLong.cs new file mode 100644 index 00000000..dcd5e588 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/LogDayLong.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShardingCore.Test.Domain.Entities +{ + public class LogDayLong + { + public Guid Id { get; set; } + public string LogLevel { get; set; } + public string LogBody { get; set; } + public long LogTime { get; set; } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Entities/LogMonthLong.cs b/src/ShardingCore.Test7x/Domain/Entities/LogMonthLong.cs new file mode 100644 index 00000000..043ad7e2 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/LogMonthLong.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShardingCore.Test.Domain.Entities +{ + public class LogMonthLong + { + public string Id { get; set; } + public string Body { get; set; } + public long LogTime { get; set; } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Entities/LogNoSharding.cs b/src/ShardingCore.Test7x/Domain/Entities/LogNoSharding.cs new file mode 100644 index 00000000..56cf6fd9 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/LogNoSharding.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShardingCore.Test.Domain.Entities +{ + public class LogNoSharding + { + public string Id { get; set; } + public string Body { get; set; } + public DateTime CreationTime { get; set; } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Entities/LogWeekDateTime.cs b/src/ShardingCore.Test7x/Domain/Entities/LogWeekDateTime.cs new file mode 100644 index 00000000..34c3b140 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/LogWeekDateTime.cs @@ -0,0 +1,12 @@ +using System; + +namespace ShardingCore.Test.Domain.Entities +{ + public class LogWeekDateTime + { + + public string Id { get; set; } + public string Body { get; set; } + public DateTime LogTime { get; set; } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Entities/LogWeekTimeLong.cs b/src/ShardingCore.Test7x/Domain/Entities/LogWeekTimeLong.cs new file mode 100644 index 00000000..014f0886 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/LogWeekTimeLong.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShardingCore.Test.Domain.Entities +{ + public class LogWeekTimeLong + { + + public string Id { get; set; } + public string Body { get; set; } + public long LogTime { get; set; } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Entities/LogYearDateTime.cs b/src/ShardingCore.Test7x/Domain/Entities/LogYearDateTime.cs new file mode 100644 index 00000000..4d420d9f --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/LogYearDateTime.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShardingCore.Test.Domain.Entities +{ + public class LogYearDateTime + { + public Guid Id { get; set; } + public string LogBody { get; set; } + public DateTime LogTime { get; set; } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Entities/LogYearLong.cs b/src/ShardingCore.Test7x/Domain/Entities/LogYearLong.cs new file mode 100644 index 00000000..78a17aaa --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/LogYearLong.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShardingCore.Test.Domain.Entities +{ + public class LogYearLong + { + public string Id { get; set; } + public string LogBody { get; set; } + public long LogTime { get; set; } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Entities/MultiShardingOrder.cs b/src/ShardingCore.Test7x/Domain/Entities/MultiShardingOrder.cs new file mode 100644 index 00000000..2d2e124d --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/MultiShardingOrder.cs @@ -0,0 +1,11 @@ +using System; + +namespace ShardingCore.Test.Domain.Entities +{ + public class MultiShardingOrder + { + public long Id { get; set; } + public string Name { get; set; } + public DateTime CreateTime { get; set; } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Entities/Order.cs b/src/ShardingCore.Test7x/Domain/Entities/Order.cs new file mode 100644 index 00000000..a471c4ee --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/Order.cs @@ -0,0 +1,13 @@ +using System; +using ShardingCore.Core; + +namespace ShardingCore.Test.Domain.Entities +{ + public class Order + { + public Guid Id { get; set; } + public string Area { get; set; } + public long Money { get; set; } + public DateTime CreateTime { get; set; } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Entities/SysUserMod.cs b/src/ShardingCore.Test7x/Domain/Entities/SysUserMod.cs new file mode 100644 index 00000000..1eefd3bb --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/SysUserMod.cs @@ -0,0 +1,32 @@ +namespace ShardingCore.Test.Domain.Entities +{ +/* +* @Author: xjm +* @Description: +* @Date: Thursday, 14 January 2021 15:36:43 +* @Email: 326308290@qq.com +*/ + public class SysUserMod: IId + { + /// + /// 用户Id用于分表 + /// + public string Id { get; set; } + /// + /// 用户名称 + /// + public string Name { get; set; } + /// + /// 用户姓名 + /// + public int Age { get; set; } + public int AgeGroup { get; set; } + + } + + public interface IId + { + string Id { get; set; } + } + +} \ No newline at end of file diff --git a/src/ShardingCore.Test7x/Domain/Entities/SysUserModInt.cs b/src/ShardingCore.Test7x/Domain/Entities/SysUserModInt.cs new file mode 100644 index 00000000..a77b9d4c --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/SysUserModInt.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ShardingCore.Test.Domain.Entities +{ + public class SysUserModInt + { + /// + /// 用户Id用于分表 + /// + public int Id { get; set; } + /// + /// 用户名称 + /// + public string Name { get; set; } + /// + /// 用户姓名 + /// + public int Age { get; set; } + public int AgeGroup { get; set; } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Entities/SysUserSalary.cs b/src/ShardingCore.Test7x/Domain/Entities/SysUserSalary.cs new file mode 100644 index 00000000..33797926 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Entities/SysUserSalary.cs @@ -0,0 +1,39 @@ +namespace ShardingCore.Test.Domain.Entities +{ +/* +* @Author: xjm +* @Description: +* @Date: Monday, 01 February 2021 15:43:22 +* @Email: 326308290@qq.com +*/ + public class SysUserSalary + { + public string Id { get; set; } + public string UserId { get; set; } + /// + /// 每月的金额 + /// + public int DateOfMonth { get; set; } + /// + /// 工资 + /// + public int Salary { get; set; } + /// + /// 工资 + /// + public long SalaryLong { get; set; } + + /// + /// 工资 + /// + public decimal SalaryDecimal { get; set; } + /// + /// 工资 + /// + public double SalaryDouble { get; set; } + /// + /// 工资 + /// + public float SalaryFloat { get; set; } + } +} \ No newline at end of file diff --git a/src/ShardingCore.Test7x/Domain/Maps/LogDayLongMap.cs b/src/ShardingCore.Test7x/Domain/Maps/LogDayLongMap.cs new file mode 100644 index 00000000..06b0e628 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/LogDayLongMap.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ + public class LogDayLongMap:IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.LogLevel).IsRequired().IsUnicode(false).HasMaxLength(32); + builder.Property(o => o.LogBody).IsRequired().HasMaxLength(256); + builder.ToTable(nameof(LogDayLong)); + } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Maps/LogDayMap.cs b/src/ShardingCore.Test7x/Domain/Maps/LogDayMap.cs new file mode 100644 index 00000000..91e3070d --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/LogDayMap.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ + public class LogDayMap:IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.LogLevel).IsRequired().IsUnicode(false).HasMaxLength(32); + builder.Property(o => o.LogBody).IsRequired().HasMaxLength(256); + builder.ToTable(nameof(LogDay)); + } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Maps/LogMonthLongMap.cs b/src/ShardingCore.Test7x/Domain/Maps/LogMonthLongMap.cs new file mode 100644 index 00000000..40c20d46 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/LogMonthLongMap.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ + public class LogMonthLongMap:IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + + builder.HasKey(o => o.Id); + builder.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(50); + builder.Property(o => o.Body).HasMaxLength(128); + builder.ToTable(nameof(LogMonthLong)); + } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Maps/LogNoShardingMap.cs b/src/ShardingCore.Test7x/Domain/Maps/LogNoShardingMap.cs new file mode 100644 index 00000000..691d9db4 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/LogNoShardingMap.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ + public class LogNoShardingMap:IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.Id).IsRequired().HasMaxLength(50); + builder.Property(o => o.Body).HasMaxLength(256); + builder.ToTable(nameof(LogNoSharding)); + } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Maps/LogWeekDateTimeMap.cs b/src/ShardingCore.Test7x/Domain/Maps/LogWeekDateTimeMap.cs new file mode 100644 index 00000000..452d9215 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/LogWeekDateTimeMap.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ + public class LogWeekDateTimeMap:IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(50); + builder.Property(o => o.Body).HasMaxLength(128); + builder.ToTable(nameof(LogWeekDateTime)); + } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Maps/LogWeekTimeLongMap.cs b/src/ShardingCore.Test7x/Domain/Maps/LogWeekTimeLongMap.cs new file mode 100644 index 00000000..b04b108a --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/LogWeekTimeLongMap.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ + public class LogWeekTimeLongMap : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(50); + builder.Property(o => o.Body).HasMaxLength(128); + builder.ToTable(nameof(LogWeekTimeLong)); + } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Maps/LogYearDateTimeMap.cs b/src/ShardingCore.Test7x/Domain/Maps/LogYearDateTimeMap.cs new file mode 100644 index 00000000..5a1283b7 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/LogYearDateTimeMap.cs @@ -0,0 +1,22 @@ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ + public class LogYearDateTimeMap : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.LogBody).IsRequired().HasMaxLength(256); + builder.ToTable(nameof(LogYearDateTime)); + } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Maps/LogYearLongMap.cs b/src/ShardingCore.Test7x/Domain/Maps/LogYearLongMap.cs new file mode 100644 index 00000000..f091ccb0 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/LogYearLongMap.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ + public class LogYearLongMap:IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + + builder.HasKey(o => o.Id); + builder.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(50); + builder.Property(o => o.LogBody).HasMaxLength(128); + builder.ToTable(nameof(LogYearLong)); + } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Maps/MultiShardingOrderMap.cs b/src/ShardingCore.Test7x/Domain/Maps/MultiShardingOrderMap.cs new file mode 100644 index 00000000..855d910a --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/MultiShardingOrderMap.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ + public class MultiShardingOrderMap:IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.Id).ValueGeneratedNever(); + builder.Property(o => o.Name).IsRequired().IsUnicode(false).HasMaxLength(50); + builder.ToTable(nameof(MultiShardingOrder)); + } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Maps/OrderMap.cs b/src/ShardingCore.Test7x/Domain/Maps/OrderMap.cs new file mode 100644 index 00000000..97dcdad4 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/OrderMap.cs @@ -0,0 +1,16 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ + public class OrderMap:IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.Area).IsRequired().IsUnicode(false).HasMaxLength(20); + builder.ToTable(nameof(Order)); + } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Maps/SysUserModIntMap.cs b/src/ShardingCore.Test7x/Domain/Maps/SysUserModIntMap.cs new file mode 100644 index 00000000..79da8daf --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/SysUserModIntMap.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ + public class SysUserModIntMap:IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + + builder.HasKey(o => o.Id); + builder.Property(o => o.Id).ValueGeneratedNever(); + builder.Property(o => o.Name).HasMaxLength(128); + builder.ToTable(nameof(SysUserModInt)); + } + } +} diff --git a/src/ShardingCore.Test7x/Domain/Maps/SysUserModMap.cs b/src/ShardingCore.Test7x/Domain/Maps/SysUserModMap.cs new file mode 100644 index 00000000..ae495948 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/SysUserModMap.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ +/* +* @Author: xjm +* @Description: +* @Date: Thursday, 14 January 2021 15:37:33 +* @Email: 326308290@qq.com +*/ + public class SysUserModMap:IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.Id).IsRequired().HasMaxLength(128); + builder.Property(o => o.Name).HasMaxLength(128); + builder.ToTable(nameof(SysUserMod)); + } + } +} \ No newline at end of file diff --git a/src/ShardingCore.Test7x/Domain/Maps/SysUserSalaryMap.cs b/src/ShardingCore.Test7x/Domain/Maps/SysUserSalaryMap.cs new file mode 100644 index 00000000..654d4ae6 --- /dev/null +++ b/src/ShardingCore.Test7x/Domain/Maps/SysUserSalaryMap.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Domain.Maps +{ +/* +* @Author: xjm +* @Description: +* @Date: Monday, 01 February 2021 15:42:35 +* @Email: 326308290@qq.com +*/ + public class SysUserSalaryMap:IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(o => o.Id); + builder.Property(o => o.Id).IsRequired().HasMaxLength(128); + builder.Property(o => o.UserId).IsRequired().HasMaxLength(128); + builder.ToTable(nameof(SysUserSalary)); + } + } +} \ No newline at end of file diff --git a/src/ShardingCore.Test7x/ShardingCore.Test7x.csproj b/src/ShardingCore.Test7x/ShardingCore.Test7x.csproj new file mode 100644 index 00000000..bebad4ad --- /dev/null +++ b/src/ShardingCore.Test7x/ShardingCore.Test7x.csproj @@ -0,0 +1,28 @@ + + + + net6.0 + TRACE;DEBUG;EFCORE7Test; + ShardingCore.Test + latest + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/src/ShardingCore.Test7x/ShardingDefaultDbContext.cs b/src/ShardingCore.Test7x/ShardingDefaultDbContext.cs new file mode 100644 index 00000000..a8a33a93 --- /dev/null +++ b/src/ShardingCore.Test7x/ShardingDefaultDbContext.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore; +using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions; +using ShardingCore.Sharding; +using ShardingCore.Sharding.Abstractions; +using ShardingCore.Test.Domain.Maps; + +namespace ShardingCore.Test +{ + /* + * @Author: xjm + * @Description: + * @Date: 2021/8/15 10:21:03 + * @Ver: 1.0 + * @Email: 326308290@qq.com + */ + public class ShardingDefaultDbContext:AbstractShardingDbContext, IShardingTableDbContext + { + public ShardingDefaultDbContext(DbContextOptions options) : base(options) + { + } + + //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + //{ + // base.OnConfiguring(optionsBuilder); + // optionsBuilder.UseLazyLoadingProxies(); + //} + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + modelBuilder.ApplyConfiguration(new SysUserModMap()); + modelBuilder.ApplyConfiguration(new SysUserSalaryMap()); + modelBuilder.ApplyConfiguration(new OrderMap()); + modelBuilder.ApplyConfiguration(new LogDayMap()); + modelBuilder.ApplyConfiguration(new LogWeekDateTimeMap()); + modelBuilder.ApplyConfiguration(new LogWeekTimeLongMap()); + modelBuilder.ApplyConfiguration(new LogYearDateTimeMap()); + modelBuilder.ApplyConfiguration(new LogNoShardingMap()); + modelBuilder.ApplyConfiguration(new LogMonthLongMap()); + modelBuilder.ApplyConfiguration(new LogYearLongMap()); + modelBuilder.ApplyConfiguration(new SysUserModIntMap()); + modelBuilder.ApplyConfiguration(new LogDayLongMap()); + modelBuilder.ApplyConfiguration(new MultiShardingOrderMap()); + } + + public IRouteTail RouteTail { get; set; } + } +} diff --git a/src/ShardingCore.Test7x/ShardingTest.cs b/src/ShardingCore.Test7x/ShardingTest.cs new file mode 100644 index 00000000..9b545234 --- /dev/null +++ b/src/ShardingCore.Test7x/ShardingTest.cs @@ -0,0 +1,1792 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Core.QueryRouteManagers.Abstractions; +using ShardingCore.Core.RuntimeContexts; +using ShardingCore.Core.VirtualDatabase.VirtualDataSources; +using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources; +using ShardingCore.Core.VirtualRoutes.Abstractions; +using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine; +using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails; +using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions; +using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine; +using ShardingCore.Exceptions; +using ShardingCore.Extensions; +using ShardingCore.Extensions.ShardingPageExtensions; +using ShardingCore.Extensions.ShardingQueryableExtensions; +using ShardingCore.Helpers; +using ShardingCore.Sharding; +using ShardingCore.Sharding.ParallelTables; +using ShardingCore.Sharding.ReadWriteConfigurations; +using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions; +using ShardingCore.Sharding.ShardingComparision.Abstractions; +using ShardingCore.Sharding.ShardingDbContextExecutors; +using ShardingCore.Sharding.StreamMergeEngines; +using ShardingCore.TableCreator; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.Utils; +using Xunit; + +namespace ShardingCore.Test +{ + + public class ShardingTest + { + private readonly ShardingDefaultDbContext _virtualDbContext; + private readonly IShardingRouteManager _shardingRouteManager; + private readonly ActualConnectionStringManager _connectionStringManager; + private readonly IConfiguration _configuration; + private readonly IEntityMetadataManager _entityMetadataManager; + private readonly IVirtualDataSource _virtualDataSource; + private readonly ITableRouteManager _tableRouteManager; + private readonly IShardingTableCreator _shardingTableCreator; + private readonly IShardingReadWriteManager _shardingReadWriteManager; + private readonly IRouteTailFactory _routeTailFactory; + private readonly IReadWriteConnectorFactory _readWriteConnectorFactory; + private readonly IShardingConnectionStringResolver _shardingConnectionStringResolver; + private readonly ITableRouteRuleEngineFactory _tableRouteRuleEngineFactory; + private readonly IShardingComparer _shardingComparer; + + public ShardingTest(ShardingDefaultDbContext virtualDbContext, IShardingRuntimeContext shardingRuntimeContext, IConfiguration configuration) + { + _virtualDbContext = virtualDbContext; + _shardingRouteManager = shardingRuntimeContext.GetShardingRouteManager(); + _shardingReadWriteManager = shardingRuntimeContext.GetShardingReadWriteManager(); + _virtualDataSource = shardingRuntimeContext.GetVirtualDataSource(); + _connectionStringManager = new ActualConnectionStringManager(_shardingReadWriteManager, _virtualDataSource,virtualDbContext); + _configuration = configuration; + _entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); + _tableRouteManager = shardingRuntimeContext.GetTableRouteManager(); + _shardingTableCreator = shardingRuntimeContext.GetShardingTableCreator(); + _routeTailFactory = shardingRuntimeContext.GetRouteTailFactory(); + _shardingComparer = shardingRuntimeContext.GetShardingComparer(); + _readWriteConnectorFactory = shardingRuntimeContext.GetReadWriteConnectorFactory(); + _tableRouteRuleEngineFactory = shardingRuntimeContext.GetService(); + var readWriteConnectors = _virtualDataSource.ConfigurationParams.ReadWriteNodeSeparationConfigs.Select(o => _readWriteConnectorFactory.CreateConnector(_virtualDataSource.ConfigurationParams.ReadStrategy.GetValueOrDefault(), o.Key, o.Value)); + _shardingConnectionStringResolver = new ReadWriteShardingConnectionStringResolver(readWriteConnectors, _virtualDataSource.ConfigurationParams.ReadStrategy.GetValueOrDefault(), _readWriteConnectorFactory); + } + // [Fact] + // public void RouteParseCompileCacheTest() + // { + // var expressionEqualityComparer = new RouteParseExpressionEqualityComparer(); + // var virtualTable = _virtualTableManager.GetVirtualTable(); + // var virtualTableRoute = (AbstractShardingOperatorVirtualTableRoute)virtualTable.GetVirtualRoute(); + // var xxxx = "202102"; + // var queryable1 = _virtualDbContext.Set().Where(o => o.DateOfMonth >= 202102); + // var routeParseExpression1 = ShardingUtil.GetRouteParseExpression(queryable1, virtualTableRoute.EntityMetadata, + // (i, op, propertyName) => virtualTableRoute.GetRouteFilter(i, op, propertyName), true); + // var queryable2 = _virtualDbContext.Set().Where(ox => ox.DateOfMonth >= 202102); + // var routeParseExpression2 = ShardingUtil.GetRouteParseExpression(queryable2, virtualTableRoute.EntityMetadata, + // (i, op, propertyName) => virtualTableRoute.GetRouteFilter(i, op, propertyName), true); + // var xxxx1 = 202102; + // var queryable3 = _virtualDbContext.Set().Where(ox => ox.DateOfMonth >= xxxx1); + // var routeParseExpression3 = ShardingUtil.GetRouteParseExpression(queryable3, virtualTableRoute.EntityMetadata, + // (i, op, propertyName) => virtualTableRoute.GetRouteFilter(i, op, propertyName), true); + // var queryable4 = _virtualDbContext.Set().Where(o => o.DateOfMonth >= 202101); + // var routeParseExpression4 = ShardingUtil.GetRouteParseExpression(queryable4, virtualTableRoute.EntityMetadata, + // (i, op, propertyName) => virtualTableRoute.GetRouteFilter(i, op, propertyName), true); + // var queryable5 = _virtualDbContext.Set().Where(o => o.DateOfMonth > 202101); + // var routeParseExpression5 = ShardingUtil.GetRouteParseExpression(queryable5, virtualTableRoute.EntityMetadata, + // (i, op, propertyName) => virtualTableRoute.GetRouteFilter(i, op, propertyName), true); + // var queryable6 = _virtualDbContext.Set().Where(o => o.DateOfMonth == 202101); + // var routeParseExpression6 = ShardingUtil.GetRouteParseExpression(queryable6, virtualTableRoute.EntityMetadata, + // (i, op, propertyName) => virtualTableRoute.GetRouteFilter(i, op, propertyName), true); + // var queryable7 = _virtualDbContext.Set().Where(o => 202101 <= o.DateOfMonth); + // var routeParseExpression7 = ShardingUtil.GetRouteParseExpression(queryable7, virtualTableRoute.EntityMetadata, + // (i, op, propertyName) => virtualTableRoute.GetRouteFilter(i, op, propertyName), true); + // var queryable8 = _virtualDbContext.Set().Where(o => 202101 == o.DateOfMonth); + // var routeParseExpression8 = ShardingUtil.GetRouteParseExpression(queryable8, virtualTableRoute.EntityMetadata, + // (i, op, propertyName) => virtualTableRoute.GetRouteFilter(i, op, propertyName), true); + // Assert.Equal(expressionEqualityComparer.GetHashCode(routeParseExpression1), expressionEqualityComparer.GetHashCode(routeParseExpression2)); + // Assert.Equal(expressionEqualityComparer.GetHashCode(routeParseExpression1), expressionEqualityComparer.GetHashCode(routeParseExpression3)); + // Assert.NotEqual(expressionEqualityComparer.GetHashCode(routeParseExpression1), expressionEqualityComparer.GetHashCode(routeParseExpression4)); + // Assert.Equal(expressionEqualityComparer.GetHashCode(routeParseExpression4), expressionEqualityComparer.GetHashCode(routeParseExpression5)); + // Assert.NotEqual(expressionEqualityComparer.GetHashCode(routeParseExpression5), expressionEqualityComparer.GetHashCode(routeParseExpression6)); + // Assert.Equal(expressionEqualityComparer.GetHashCode(routeParseExpression4), expressionEqualityComparer.GetHashCode(routeParseExpression7)); + // Assert.Equal(expressionEqualityComparer.GetHashCode(routeParseExpression6), expressionEqualityComparer.GetHashCode(routeParseExpression8)); + // + // } + + [Fact] + public async Task GenericTest() + { + var a = new DefaultPhysicDataSource("aaa", "aaa", true); + var b = new DefaultPhysicDataSource("aaa", "aaa1", false); + Assert.Equal(a, b); + var x = new EntityMetadata(typeof(LogDay)); + var y = new EntityMetadata(typeof(LogDay)); + Assert.Equal(x, y); + var dateTime = new DateTime(2021, 1, 1); + var logDays = Enumerable.Range(0, 100).Select(o => new LogDay() { Id = Guid.NewGuid(), LogLevel = "info", LogBody = o.ToString(), LogTime = dateTime.AddDays(o) }).ToList(); + + var bulkShardingTableEnumerable = _virtualDbContext.BulkShardingTableEnumerable(logDays); + + Assert.Equal(100, bulkShardingTableEnumerable.Count); + var bulkShardingEnumerable = _virtualDbContext.BulkShardingEnumerable(logDays); + Assert.Equal(1, bulkShardingEnumerable.Count); + foreach (var (key, value) in bulkShardingEnumerable) + { + Assert.Equal(100, value.Count); + } + + _virtualDbContext.Set().Where(o => o.Id == "300").ShardingPrint(); + var contains = await _virtualDbContext.Set().Where(o => o.Id == "300").Select(o => o.Id).ContainsAsync("300"); + Assert.True(contains); + + try + { + var x1 = _virtualDataSource.GetPhysicDataSource("abc"); + } + catch (Exception e) + { + Assert.Equal(typeof(ShardingCoreNotFoundException), e.GetType()); + } + + var queryable = new List().Select(o => new SequenceClass { Id = "123", T = o }).AsQueryable(); + var sourceType = queryable.GetType().GetSequenceType(); + Assert.Equal(typeof(SequenceClass), sourceType); + try + { + _shardingTableCreator.CreateTable("A", "202105"); + } + catch (Exception e) + { + Assert.Equal(typeof(ShardingCoreException), e.GetType()); + } + + var orderMetadata = _entityMetadataManager.TryGet(); + Assert.NotNull(orderMetadata); + var isKey1 = orderMetadata.ShardingDataSourceFieldIsKey(); + Assert.False(isKey1); + var isKey2 = orderMetadata.ShardingTableFieldIsKey(); + Assert.False(isKey2); + var userModMetadata = _entityMetadataManager.TryGet(); + Assert.NotNull(userModMetadata); + var isKey3 = userModMetadata.ShardingDataSourceFieldIsKey(); + Assert.False(isKey3); + var isKey4 = userModMetadata.ShardingTableFieldIsKey(); + Assert.True(isKey4); + + await _virtualDbContext.AddRangeAsync(logDays); + var bulkShardingExpression = _virtualDbContext.BulkShardingExpression(o => new[] { "A", "B" }.Contains(o.Area)); + + Assert.Equal(2, bulkShardingExpression.Count); + Assert.True(bulkShardingExpression.ContainsKey("A")); + Assert.True(bulkShardingExpression.ContainsKey("B")); + + var bulkShardingTableExpression = _virtualDbContext.BulkShardingTableExpression(o => o.Id == Guid.NewGuid().ToString()); + Assert.Equal(1, bulkShardingTableExpression.Count()); + + var noShardingExpression = _virtualDbContext.BulkShardingExpression(o => o.Id == "123"); + Assert.Equal(1, noShardingExpression.Count()); + + var isShardingDbContext = _virtualDbContext.IsShardingDbContext(); + Assert.True(isShardingDbContext); + var isShardingTableDbContext = _virtualDbContext.IsShardingTableDbContext(); + Assert.True(isShardingTableDbContext); + var shardingDbContext = _virtualDbContext.GetType().IsShardingDbContext(); + Assert.True(shardingDbContext); + var shardingTableDbContext = _virtualDbContext.GetType().IsShardingTableDbContext(); + Assert.True(shardingTableDbContext); + var emptyTailIdentity = new SingleQueryRouteTail(string.Empty).GetRouteTailIdentity(); + var aTailIdentity = new SingleQueryRouteTail("a").GetRouteTailIdentity(); + var bTailIdentity = new SingleQueryRouteTail("b").GetRouteTailIdentity(); + var dics = new SortedDictionary(new NoShardingFirstComparer()); + var dicTails = new List() { emptyTailIdentity, aTailIdentity, bTailIdentity }; + for (int i = 0; i < 10; i++) + { + dics.Clear(); + var reOrderList = dicTails.OrderBy(o => Guid.NewGuid()).ToList(); + foreach (var tail in reOrderList) + { + dics.Add(tail, null); + } + Assert.Equal($"{emptyTailIdentity},{aTailIdentity},{bTailIdentity}", string.Join(",", dics.Keys)); + } + + var x1x1 = new ParallelTableGroupNode(new HashSet() + { new ParallelTableComparerType(typeof(SysUserMod)), new ParallelTableComparerType(typeof(SysUserSalary)) }); + var x2x2 = new ParallelTableGroupNode(new HashSet() + { new ParallelTableComparerType(typeof(SysUserSalary)),new ParallelTableComparerType(typeof(SysUserMod)), }); + Assert.Equal(x1x1, x2x2); + Assert.Equal(x1x1.GetHashCode(), x2x2.GetHashCode()); + var succeedAddConnectionString = _shardingConnectionStringResolver.AddConnectionString("X", "Data Source=localhost;Initial Catalog=ShardingCoreDBC;Integrated Security=True;", null); + Assert.True(succeedAddConnectionString); + var connectionString = _shardingConnectionStringResolver.GetConnectionString("X", null); + Assert.Equal("Data Source=localhost;Initial Catalog=ShardingCoreDBC;Integrated Security=True;", connectionString); + } + + public class SequenceClass + { + public string Id { get; set; } + public string T { get; set; } + } + + [Fact] + public async Task TestMultiShardingProperty() + { + + var multiOrder = await _virtualDbContext.Set().Where(o => o.Id == 232398109278351360).FirstOrDefaultAsync(); + Assert.NotNull(multiOrder); + var allMultiOrders = await _virtualDbContext.Set().ToListAsync(); + Assert.Equal(8, allMultiOrders.Count); + var longs = new[] { 232398109278351360, 255197859283087360 }; + var multiOrders = await _virtualDbContext.Set().Where(o => longs.Contains(o.Id)).ToListAsync(); + Assert.Equal(2, multiOrders.Count); + var multinNotOrders = await _virtualDbContext.Set().Where(o => !longs.Contains(o.Id)).ToListAsync(); + Assert.Equal(6, multinNotOrders.Count); + var dateTime = new DateTime(2021, 11, 1); + var multiOrder404 = await _virtualDbContext.Set().Where(o => o.Id == 250345338962063360 && o.CreateTime < dateTime).FirstOrDefaultAsync(); + Assert.Null(multiOrder404); + } + [Fact] + public void TestEntityMetadataManager() + { + var objMetadata0 = _entityMetadataManager.TryGet(typeof(object)); + Assert.Null(objMetadata0); + var objMetadata1 = _entityMetadataManager.TryGet(); + Assert.Null(objMetadata1); + + var objMetadata2 = _entityMetadataManager.TryGet(typeof(SysUserMod)); + Assert.NotNull(objMetadata2); + var objMetadata3 = _entityMetadataManager.TryGet(); + Assert.NotNull(objMetadata3); + var sysUserModIsShardingTable0 = _entityMetadataManager.IsShardingTable(typeof(SysUserMod)); + Assert.True(sysUserModIsShardingTable0); + var sysUserModIsShardingTable1 = _entityMetadataManager.IsShardingTable(); + Assert.True(sysUserModIsShardingTable1); + var sysUserModIsShardingDataSource0 = _entityMetadataManager.IsShardingDataSource(typeof(SysUserMod)); + Assert.False(sysUserModIsShardingDataSource0); + var sysUserModIsShardingDataSource1 = _entityMetadataManager.IsShardingDataSource(); + Assert.False(sysUserModIsShardingDataSource1); + } + [Fact] + public void TestShardingComparer() + { + var x = new Guid("7CDE28F8-D548-B96D-1C61-39FFE37AE492"); + var y = new Guid("3425D899-291D-921B-DDE4-49FFE37AE493"); + //asc y 0); + //asc x().Where(o=>o.Id=="339"); + // var routeResults1 = _tableRouteRuleEngineFactory.Route(queryable1); + // Assert.Equal(1,routeResults1.Count()); + // Assert.Equal(1,routeResults1.FirstOrDefault().ReplaceTables.Count()); + // Assert.Equal("0",routeResults1.FirstOrDefault().ReplaceTables.FirstOrDefault().Tail); + // Assert.Equal(nameof(SysUserMod),routeResults1.FirstOrDefault().ReplaceTables.FirstOrDefault().OriginalName); + // var ids = new[] {"339", "124","142"}; + // var queryable2= _virtualDbContext.Set().Where(o=>ids.Contains(o.Id)); + // var routeResult2s = _tableRouteRuleEngineFactory.Route(queryable2); + // Assert.Equal(2,routeResult2s.Count()); + // Assert.Equal(1,routeResult2s.FirstOrDefault().ReplaceTables.Count()); + // Assert.Equal(2,routeResult2s.SelectMany(o=>o.ReplaceTables).Count()); + // Assert.Equal(true,routeResult2s.SelectMany(o=>o.ReplaceTables).All(o=>new[]{"0","1"}.Contains(o.Tail))); + //} + [Fact] + public async Task ToList_All_Route_Test() + { + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("00"); + + var mod00s = await _virtualDbContext.Set().ToListAsync(); + Assert.Equal(333, mod00s.Count); + } + var mods = await _virtualDbContext.Set().ToListAsync(); + Assert.Equal(1000, mods.Count); + + var modOrders1 = await _virtualDbContext.Set().OrderBy(o => o.Age).ToListAsync(); + int ascAge = 1; + foreach (var sysUserMod in modOrders1) + { + Assert.Equal(ascAge, sysUserMod.Age); + ascAge++; + } + + + var modOrders2 = await _virtualDbContext.Set().OrderByDescending(o => o.Age).ToListAsync(); + int descAge = 1000; + foreach (var sysUserMod in modOrders2) + { + Assert.Equal(descAge, sysUserMod.Age); + descAge--; + } + } + [Fact] + public async Task ToList_All_Test() + { + + var mods = await _virtualDbContext.Set().ToListAsync(); + Assert.Equal(1000, mods.Count); + + var modOrders1 = await _virtualDbContext.Set().OrderBy(o => o.Age).ToListAsync(); + int ascAge = 1; + foreach (var sysUserMod in modOrders1) + { + Assert.Equal(ascAge, sysUserMod.Age); + ascAge++; + } + + var modOrders2 = await _virtualDbContext.Set().OrderByDescending(o => o.Age).ToListAsync(); + int descAge = 1000; + foreach (var sysUserMod in modOrders2) + { + Assert.Equal(descAge, sysUserMod.Age); + descAge--; + } + + + + var pageResult = await _virtualDbContext.Set().Skip(10).Take(10).OrderByDescending(o => o.Age).ToListAsync(); + Assert.Equal(10, pageResult.Count); + int pageDescAge = 990; + foreach (var sysUserMod in pageResult) + { + Assert.Equal(pageDescAge, sysUserMod.Age); + pageDescAge--; + } + var skip10First = await _virtualDbContext.Set().Skip(10).OrderByDescending(o => o.Age).FirstOrDefaultAsync(); + Assert.Equal(skip10First, pageResult[0]); + } + + [Fact] + public async Task ToList_Join_Test() + { + var list111 = await (from u in _virtualDbContext.Set() + join salary in _virtualDbContext.Set() + on u.Id equals salary.UserId + select new + { + u.Id, + u.Age, + Salary = salary.Salary, + DateOfMonth = salary.DateOfMonth, + Name = u.Name + }).CountAsync(); + var list = await (from u in _virtualDbContext.Set() + join salary in _virtualDbContext.Set() + on u.Id equals salary.UserId + select new + { + u.Id, + u.Age, + Salary = salary.Salary, + DateOfMonth = salary.DateOfMonth, + Name = u.Name + }).ToListAsync(); + + var list2 = list.OrderBy(o => o.Age).Select(o => o.Age).Distinct().ToList(); + Assert.Equal(24000, list.Count()); + Assert.Equal(24, list.Count(o => o.Name == "name_200")); + + + var queryable = (from u in _virtualDbContext.Set().Where(o => o.Id == "300") + join salary in _virtualDbContext.Set() + on u.Id equals salary.UserId + select new + { + Salary = salary.Salary, + DateOfMonth = salary.DateOfMonth, + Name = u.Name + }); + var list1 = await queryable.ToListAsync(); + Assert.Equal(24, list1.Count()); + Assert.DoesNotContain(list1, o => o.Name != "name_300"); + // await _virtualDbContext.Set().Where(o=>o.Age==1).ExecuteUpdateAsync( + // s => s.SetProperty(b => b.Name, b => b.Name + " *Featured!*")); + var queryable1 = (from u in _virtualDbContext.Set().Where(o => o.Id == "300") + join salary in _virtualDbContext.Set().Where(o => o.DateOfMonth == 202005) + on u.Id equals salary.UserId + select new + { + Salary = salary.Salary, + DateOfMonth = salary.DateOfMonth, + Name = u.Name + }); + var list3 = await queryable1.ToListAsync(); + Assert.Equal(1, list3.Count()); + Assert.Contains(list3, o => o.Name == "name_300"); + var firstOrDefaultAsync = await queryable1.OrderBy(o => o.DateOfMonth).FirstOrDefaultAsync(); + Assert.NotNull(firstOrDefaultAsync); + var firstOrDefault = queryable1.OrderBy(o => o.DateOfMonth).FirstOrDefault(); + Assert.NotNull(firstOrDefault); + Assert.Equal(firstOrDefaultAsync, firstOrDefault); + } + + [Fact] + public async Task ToList_OrderBy_Asc_Desc_Test() + { + var modascs = await _virtualDbContext.Set().OrderBy(o => o.Age).ToListAsync(); + Assert.Equal(1000, modascs.Count); + var i = 1; + foreach (var age in modascs) + { + Assert.Equal(i, age.Age); + i++; + } + + var moddescs = await _virtualDbContext.Set().OrderByDescending(o => o.Age).ToListAsync(); + Assert.Equal(1000, moddescs.Count); + var j = 1000; + foreach (var age in moddescs) + { + Assert.Equal(j, age.Age); + j--; + } + } + + [Fact] + public async Task ToList_Id_In_Test() + { + var ids = new[] { "1", "2", "3", "4" }; + var sysUserMods = await _virtualDbContext.Set().Where(o => new List { "1", "2", "3", "4" }.Contains(o.Id)).ToListAsync(); + foreach (var id in ids) + { + Assert.Contains(sysUserMods, o => o.Id == id); + } + + Assert.DoesNotContain(sysUserMods, o => o.Age > 4); + } + + [Fact] + public async Task ToList_Id_Eq_Test() + { + var id = 3; + var mods = await _virtualDbContext.Set().Where(o => o.Id == id.ToString()).ToListAsync(); + Assert.Single(mods); + var mods1 = await _virtualDbContext.Set().Where(o => o.Id == "4").ToListAsync(); + Assert.Single(mods1); + Assert.Equal("3", mods[0].Id); + } + + [Fact] + public async Task ToList_Id_Not_Eq_Test() + { + var methodValue = new MethodValue() { AA = "7" }; + var mods123 = await _virtualDbContext.Set().Where(o => o.Id == methodValue.GetAa()).FirstOrDefaultAsync(); + Assert.NotNull(mods123); + Assert.Equal(mods123.Id, "7"); + var mods12 = await _virtualDbContext.Set().Where(o => new List { "3", "4" }.Contains(o.Id)).ToListAsync(); + Assert.Contains(mods12, o => o.Id == "3" || o.Id == "4"); + var mods = await _virtualDbContext.Set().Where(o => o.Id != "3").ToListAsync(); + Assert.Equal(999, mods.Count); + Assert.DoesNotContain(mods, o => o.Id == "3"); + } + public class MethodValue + { + public string AA { get; set; } + + public string GetAa() + { + return AA; + } + } + + [Fact] + public async Task ToList_Id_Not_Eq_Skip_Test() + { + var mods = await _virtualDbContext.Set().Where(o => o.Id != "3").OrderBy(o => o.Age).Skip(2).ToListAsync(); + Assert.Equal(997, mods.Count); + Assert.DoesNotContain(mods, o => o.Id == "3"); + Assert.Equal(4, mods[0].Age); + Assert.Equal(5, mods[1].Age); + + var modsDesc = await _virtualDbContext.Set().Where(o => o.Id != "3").OrderByDescending(o => o.Age).Skip(13).ToListAsync(); + Assert.Equal(986, modsDesc.Count); + Assert.DoesNotContain(mods, o => o.Id == "3"); + Assert.Equal(987, modsDesc[0].Age); + Assert.Equal(986, modsDesc[1].Age); + } + + [Fact] + public async Task ToList_Name_Eq_Test() + { + var mods = await _virtualDbContext.Set().Where(o => o.Name == "name_3").ToListAsync(); + Assert.Single(mods); + Assert.Equal("3", mods[0].Id); + } + + [Fact] + public async Task ToList_Id_Eq_Not_In_Db_Test() + { + var mod1s = await _virtualDbContext.Set().Where(o => string.Compare(((IId)o).Id, "1001") == 0).ToListAsync(); + var mod2s = await _virtualDbContext.Set().Where(o => string.Compare("1001", o.Id) == 0).ToListAsync(); + var mod3s = await _virtualDbContext.Set().Where(o => "1001".CompareTo(o.Id) == 0).ToListAsync(); + var mod4s = await _virtualDbContext.Set().Where(o => o.Id.CompareTo("1001") == 0).ToListAsync(); + var mods = await _virtualDbContext.Set().Where(o => o.Id == "1001").ToListAsync(); + Assert.Empty(mods); + } + + [Fact] + public async Task ToList_Name_Eq_Not_In_Db_Test() + { + var mods = await _virtualDbContext.Set().Where(o => o.Name == "name_1001").ToListAsync(); + Assert.Empty(mods); + } + + [Fact] + public async Task FirstOrDefault_Order_By_Id_Test() + { + var sysUserModAge = await _virtualDbContext.Set().OrderBy(o => o.Age).FirstOrDefaultAsync(); + Assert.True(sysUserModAge != null && sysUserModAge.Id == "1"); + var sysUserModAgeDesc = await _virtualDbContext.Set().OrderByDescending(o => o.Age).FirstOrDefaultAsync(); + Assert.True(sysUserModAgeDesc != null && sysUserModAgeDesc.Id == "1000"); + var sysUserMod = await _virtualDbContext.Set().OrderBy(o => o.Id).FirstOrDefaultAsync(); + Assert.True(sysUserMod != null && sysUserMod.Id == "1"); + + var sysUserModDesc = await _virtualDbContext.Set().OrderByDescending(o => o.Id).FirstOrDefaultAsync(); + Assert.True(sysUserModDesc != null && sysUserModDesc.Id == "999"); + + } + + + [Fact] + public async Task FirstOrDefault2() + { + var sysUserModabxxxxx1 = await _virtualDbContext.Set().Where(o => o.DateOfMonth >= 202102).FirstOrDefaultAsync(); + var sysUserModabxxxxx71 = await _virtualDbContext.Set().Where(ox => ox.DateOfMonth >= 202102).FirstOrDefaultAsync(); + var xxxx1 = 202102; + var sysUserModabxxxxx72 = await _virtualDbContext.Set().Where(ox => ox.DateOfMonth >= xxxx1).FirstOrDefaultAsync(); + var sysUserModabxxxxx2 = await _virtualDbContext.Set().Where(o => o.DateOfMonth >= 202101).FirstOrDefaultAsync(); + var sysUserModabxxxxx3 = await _virtualDbContext.Set().Where(o => o.DateOfMonth > 202102).FirstOrDefaultAsync(); + var sysUserModabxxxxx4 = await _virtualDbContext.Set().Where(o => o.DateOfMonth == 202102).FirstOrDefaultAsync(); + var sysUserModabxxxxx5 = await _virtualDbContext.Set().Where(o => o.DateOfMonth < 202102).FirstOrDefaultAsync(); + var sysUserModabxxxxx6 = await _virtualDbContext.Set().Where(o => o.DateOfMonth <= 202102).FirstOrDefaultAsync(); + var next = "1"; + var sysUserMod1 = await _virtualDbContext.Set().Where(o => o.Id == next).FirstOrDefaultAsync(); + var sysUserModabxxx = await _virtualDbContext.Set().Where(o => o.Name == "name_2").FirstOrDefaultAsync(); + var sysUserModabxxx11 = await _virtualDbContext.Set().Where(o => o.Name == "name_2" || o.Name == "name_3").FirstOrDefaultAsync(); + var x = new Object[] { "1", "2" }; + var sysUserModab = await _virtualDbContext.Set().Where(o => o.Id.Equals("1")).FirstOrDefaultAsync(); + Assert.NotNull(sysUserModab); + Assert.True(sysUserModab.Id == "1"); + var sysUserModaa = await _virtualDbContext.Set().Where(o => "1".Equals(o.Id)).FirstOrDefaultAsync(); + Assert.NotNull(sysUserModaa); + Assert.True(sysUserModaa.Id == "1"); + var sysUserMod = await _virtualDbContext.Set().Where(o => o.Id == "1").FirstOrDefaultAsync(); + Assert.NotNull(sysUserMod); + Assert.True(sysUserMod.Id == "1"); + Assert.Equal(sysUserModaa, sysUserMod); + var sysUserModxx = await _virtualDbContext.Set().Where(o => x.Contains(o.Id)).FirstOrDefaultAsync(); + Assert.NotNull(sysUserModxx); + Assert.True(x.Contains(sysUserModxx.Id)); + Assert.NotNull(sysUserMod); + var userMod = _virtualDbContext.Set().Find("1"); + Assert.Equal(sysUserMod, userMod); + Assert.True(sysUserMod.Id == "1"); + var user198 = await _virtualDbContext.Set().FirstOrDefaultAsync(o => o.Id == "198"); + Assert.True(user198.Id == "198"); + var userId198 = await _virtualDbContext.Set().Where(o => o.Id == "198").Select(o => o.Id).FirstOrDefaultAsync(); + Assert.Equal(userId198, "198"); + } + + [Fact] + public async Task FirstOrDefault3() + { + var sysUserMod = await _virtualDbContext.Set().Where(o => o.Name == "name_2").FirstOrDefaultAsync(); + Assert.NotNull(sysUserMod); + Assert.Equal("2", sysUserMod.Id); + var sysUserMod2 = await _virtualDbContext.Set().Where(o => o.Name == "name_2").Select(o => new + { + Name = o.Name + }).FirstOrDefaultAsync(); + var sysUserMod1 = await _virtualDbContext.Set().Where(o => o.Name == "name_2").Select(o => new TestClass(o.Name, "") { Id = o.Id }).FirstOrDefaultAsync(); + Assert.NotNull(sysUserMod1); + + } + public class TestClass + { + public string Name { get; } + public string Aa { get; } + public string Id { get; set; } + + public TestClass(string name, string aa) + { + Name = name; + Aa = aa; + } + } + + [Fact] + public async Task FirstOrDefault4() + { + var sysUserMod = await _virtualDbContext.Set().Where(o => o.Id != "1").FirstOrDefaultAsync(); + Assert.NotNull(sysUserMod); + Assert.True(sysUserMod.Id != "1"); + } + + [Fact] + public async Task FirstOrDefault5() + { + var sysUserMod = await _virtualDbContext.Set().Where(o => o.Name == "name_1001").FirstOrDefaultAsync(); + Assert.Null(sysUserMod); + } + + + [Fact] + public async Task Count_Test() + { + var a = await _virtualDbContext.Set().Where(o => o.Name == "name_1000").CountAsync(); + Assert.Equal(1, a); + var b = await _virtualDbContext.Set().Where(o => o.Name != "name_1000").CountAsync(); + Assert.Equal(999, b); + } + + [Fact] + public async Task Sum_Test() + { + var a = await _virtualDbContext.Set().SumAsync(o => o.Age); + var expected = 0; + for (int i = 1; i <= 1000; i++) + { + expected += i; + } + + Assert.Equal(expected, a); + var b = await _virtualDbContext.Set().Where(o => o.Name != "name_1000").SumAsync(o => o.Age); + Assert.Equal(expected - 1000, b); + } + + [Fact] + public async Task Max_Test() + { + var a = await _virtualDbContext.Set().MaxAsync(o => o.Age); + Assert.Equal(1000, a); + var b = await _virtualDbContext.Set().Where(o => o.Name != "name_1000").MaxAsync(o => o.Age); + Assert.Equal(999, b); + var c = await _virtualDbContext.Set().Where(o => o.Age < 500).MaxAsync(o => o.Age); + Assert.Equal(499, c); + var e = await _virtualDbContext.Set().Where(o => o.Age <= 500).MaxAsync(o => o.Age); + Assert.Equal(500, e); + } + + [Fact] + public async Task Max_Join_Test() + { + var queryable = (from u in _virtualDbContext.Set().Where(o => o.Id == "300") + join salary in _virtualDbContext.Set() + on u.Id equals salary.UserId + select new + { + Salary = salary.Salary, + DateOfMonth = salary.DateOfMonth, + Name = u.Name + }); + var maxSalary = await queryable.MaxAsync(o => o.Salary); + Assert.Equal(1390000, maxSalary); + } + + [Fact] + public async Task Min_Test() + { + var a = await _virtualDbContext.Set().MinAsync(o => o.Age); + Assert.Equal(1, a); + var b = await _virtualDbContext.Set().Where(o => o.Name != "name_1").MinAsync(o => o.Age); + Assert.Equal(2, b); + var c = await _virtualDbContext.Set().Where(o => o.Age > 500).MinAsync(o => o.Age); + Assert.Equal(501, c); + var e = await _virtualDbContext.Set().Where(o => o.Age >= 500).MinAsync(o => o.Age); + Assert.Equal(500, e); + } + + [Fact] + public async Task Any_Test() + { + var a = await _virtualDbContext.Set().AnyAsync(o => o.Age == 100); + Assert.True(a); + var b = await _virtualDbContext.Set().Where(o => o.Name != "name_1").AnyAsync(o => o.Age == 1); + Assert.False(b); + var c = await _virtualDbContext.Set().Where(o => o.Age > 500).AnyAsync(o => o.Age <= 500); + Assert.False(c); + var e = await _virtualDbContext.Set().Where(o => o.Age >= 500).AnyAsync(o => o.Age <= 500); + Assert.True(e); + } + + [Fact] + public async Task Group_Test() + { + var ids = new[] { "200", "300" }; + var dateOfMonths = new[] { 202111, 202110 }; + var group = await (from u in _virtualDbContext.Set() + .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth)) + group u by new + { + UId = u.UserId + } + into g + select new + { + GroupUserId = g.Key.UId, + Count = g.Count(), + TotalSalary = g.Sum(o => o.Salary), + AvgSalary = g.Average(o => o.Salary), + AvgSalaryDecimal = g.Average(o => o.SalaryDecimal), + MinSalary = g.Min(o => o.Salary), + MaxSalary = g.Max(o => o.Salary) + }).ToListAsync(); + Assert.Equal(2, group.Count); + Assert.Equal(2, group[0].Count); + Assert.Equal(2260000, group[0].TotalSalary); + Assert.Equal(1130000, group[0].AvgSalary); + Assert.Equal(11300, group[0].AvgSalaryDecimal); + Assert.Equal(1120000, group[0].MinSalary); + Assert.Equal(1140000, group[0].MaxSalary); + } + + [Fact] + public async Task Group_Test1() + { + var ids = new[] { "200", "300" }; + var dateOfMonths = new[] { 202111, 202110 }; + var dateTime = DateTime.Now; + + var sql = from u in _virtualDbContext.Set() + group u by u.UserId + into g + select new + { + UI = g.Key, + x = g.Sum(o => o.SalaryDecimal), + Now = dateTime + }; + var listAsync = await sql.ToListAsync(); + var group = await (from u in _virtualDbContext.Set() + .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth)) + group u by new + { + UId = u.UserId + } + into g + select new + { + GroupUserId = g.Key.UId, + Count = g.Count(), + TotalSalary = g.Sum(o => o.Salary), + AvgSalary = g.Average(o => o.Salary), + AvgSalaryDecimal = g.Average(o => o.SalaryDecimal), + MinSalary = g.Min(o => o.Salary), + MaxSalary = g.Max(o => o.Salary) + }).ToListAsync(); + Assert.Equal(2, group.Count); + Assert.Equal(2, group[0].Count); + Assert.Equal(2260000, group[0].TotalSalary); + Assert.Equal(1130000, group[0].AvgSalary); + Assert.Equal(11300, group[0].AvgSalaryDecimal); + Assert.Equal(1120000, group[0].MinSalary); + Assert.Equal(1140000, group[0].MaxSalary); + } + + [Fact] + public async Task OrderCountTest() + { + var asyncCount = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(320, asyncCount); + var syncCount = _virtualDbContext.Set().Count(); + Assert.Equal(320, syncCount); + + var countA = await _virtualDbContext.Set().CountAsync(o => o.Area == "A"); + var countB = await _virtualDbContext.Set().CountAsync(o => o.Area == "B"); + var countC = await _virtualDbContext.Set().CountAsync(o => o.Area == "C"); + Assert.Equal(320, countA + countB + countC); + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var fourCount = await _virtualDbContext.Set().Where(o => o.CreateTime >= fourBegin && o.CreateTime < fiveBegin).CountAsync(); + Assert.Equal(30, fourCount); + } + [Fact] + public async Task OrderFirstTest() + { + var threeMonth = new DateTime(2021, 3, 1); + var order = await _virtualDbContext.Set().FirstOrDefaultAsync(o => o.CreateTime == threeMonth);//��59�� 1��31��2��28�� + Assert.NotNull(order); + Assert.Equal(59, order.Money); + Assert.Equal("C", order.Area); + } + [Fact] + public async Task OrderOrderTest() + { + var orders = await _virtualDbContext.Set().OrderBy(o => o.CreateTime).ToListAsync(); + Assert.Equal(320, orders.Count); + var i = 0; + foreach (var order in orders) + { + Assert.Equal(i, order.Money); + i++; + } + + var threeMonth = new DateTime(2021, 3, 1); + var orderPage = await _virtualDbContext.Set().Where(o => o.CreateTime > threeMonth).OrderByDescending(o => o.CreateTime).ToShardingPageAsync(1, 20); + Assert.Equal(20, orderPage.Data.Count); + Assert.Equal(260, orderPage.Total); + + + var j = 319; + foreach (var order in orderPage.Data) + { + Assert.Equal(j, order.Money); + j--; + } + + + var orderPage1 = await _virtualDbContext.Set().Where(o => o.CreateTime > threeMonth).OrderBy(o => o.CreateTime).ToShardingPageAsync(1, 20); + Assert.Equal(20, orderPage1.Data.Count); + Assert.Equal(260, orderPage1.Total); + + + var j1 = 60; + foreach (var order in orderPage1.Data) + { + Assert.Equal(j1, order.Money); + j1++; + } + } + + [Fact] + public async Task LogDayCountTest() + { + var countAsync = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(3000, countAsync); + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var fourCount = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).CountAsync(); + Assert.Equal(300, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("20210102"); + var countAsync1 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(10, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintTail("20210103", "20210104"); + var countAsync2 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(20, countAsync2); + } + } + [Fact] + public void LogDayTableSeparatorTest() + { + var tableRoute = _tableRouteManager.GetRoute(typeof(LogDay)); + var virtualTableName = tableRoute.EntityMetadata.LogicTableName; + Assert.Equal(nameof(LogDay), virtualTableName); + + Assert.True(string.IsNullOrWhiteSpace(tableRoute.EntityMetadata.TableSeparator)); + var entityMetadata = _entityMetadataManager.TryGet(); + Assert.NotNull(entityMetadata); + var isShardingTable = entityMetadata.IsShardingTable(); + Assert.True(isShardingTable); + var isShardingDataSource = entityMetadata.IsShardingDataSource(); + Assert.False(isShardingDataSource); + var emptySeparator = string.IsNullOrWhiteSpace(entityMetadata.TableSeparator); + Assert.True(emptySeparator); + Assert.Null(entityMetadata.AutoCreateDataSourceTable); + } + + [Fact] + public async Task LogDayShardingPage() + { + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var page = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(300, page.Total); + + var page1 = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(300, page1.Total); + } + + [Fact] + public async Task Order_Average() + { + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var moneyAverage = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => o.Money).AverageAsync(); + Assert.Equal(105, moneyAverage); + + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("C"); + var sum = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => o.Money).SumAsync(); + Assert.Equal(0, sum); + var sum1 = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (long?)o.Money).SumAsync(); + Assert.Equal(0, sum1); + var sum2 = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (int)o.Money).SumAsync(); + Assert.Equal(0, sum2); + var sum3 = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (int?)o.Money).SumAsync(); + Assert.Equal(0, sum3); + var sum4 = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (decimal)o.Money).SumAsync(); + Assert.Equal(0, sum4); + var sum5 = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (decimal?)o.Money).SumAsync(); + Assert.Equal(0, sum5); + var sum6 = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (double)o.Money).SumAsync(); + Assert.Equal(0, sum6); + var sum7 = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (double?)o.Money).SumAsync(); + Assert.Equal(0, sum7); + var sum8 = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (float)o.Money).SumAsync(); + Assert.Equal(0, sum8); + var sum9 = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (float?)o.Money).SumAsync(); + Assert.Equal(0, sum9); + } + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintDataSource("C"); + var sum = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => o.Money).SumAsync(); + Assert.Equal(0, sum); + } + + var max = await _virtualDbContext.Set().MaxAsync(o => o.Money); + Assert.Equal(319, max); + var all = await _virtualDbContext.Set().AllAsync(o => o.Money <= 321); + Assert.True(all); + var longCount = await _virtualDbContext.Set().LongCountAsync(); + Assert.Equal(320, longCount); + } + + [Fact] + public async Task Order_Max() + { + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + + + var moneyMax = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => o.Money).MaxAsync(); + Assert.Equal(120, moneyMax); + var moneyMax1 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (long?)o.Money).MaxAsync(); + Assert.Equal(120, moneyMax1); + var moneyMax2 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (int)o.Money).MaxAsync(); + Assert.Equal(120, moneyMax2); + var moneyMax3 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (int?)o.Money).MaxAsync(); + Assert.Equal(120, moneyMax3); + var moneyMax4 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (double)o.Money).MaxAsync(); + Assert.Equal(120, moneyMax4); + var moneyMax5 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (double?)o.Money).MaxAsync(); + Assert.Equal(120, moneyMax5); + var moneyMax6 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (float)o.Money).MaxAsync(); + Assert.Equal(120, moneyMax6); + var moneyMax7 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (float?)o.Money).MaxAsync(); + Assert.Equal(120, moneyMax7); + var moneyMax8 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (decimal)o.Money).MaxAsync(); + Assert.Equal(120, moneyMax8); + var moneyMax9 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (decimal?)o.Money).MaxAsync(); + Assert.Equal(120, moneyMax9); + + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("C"); + try + { + var max = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => o.Money).MaxAsync(); + } + catch (Exception e) + { + Assert.True(typeof(InvalidOperationException) == e.GetType() || typeof(TargetInvocationException) == e.GetType()); + Assert.True(e.Message.Contains("contains") || e.InnerException.Message.Contains("contains")); + } + } + } + [Fact] + public async Task Order_Min() + { + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + + + var moneyMin = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => o.Money).MinAsync(); + Assert.Equal(90, moneyMin); + var moneyMin1 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (long?)o.Money).MinAsync(); + Assert.Equal(90, moneyMin1); + var moneyMin2 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (int)o.Money).MinAsync(); + Assert.Equal(90, moneyMin2); + var moneyMin3 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (int?)o.Money).MinAsync(); + Assert.Equal(90, moneyMin3); + var moneyMin4 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (float)o.Money).MinAsync(); + Assert.Equal(90, moneyMin4); + var moneyMin5 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (float?)o.Money).MinAsync(); + Assert.Equal(90, moneyMin5); + var moneyMin6 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (double)o.Money).MinAsync(); + Assert.Equal(90, moneyMin6); + var moneyMin7 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (double?)o.Money).MinAsync(); + Assert.Equal(90, moneyMin7); + var moneyMin8 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (decimal)o.Money).MinAsync(); + Assert.Equal(90, moneyMin8); + var moneyMin9 = await _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (decimal?)o.Money).MinAsync(); + Assert.Equal(90, moneyMin9); + + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("C"); + try + { + var max = await _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => o.Money).MinAsync(); + } + catch (Exception e) + { + Assert.True(typeof(InvalidOperationException) == e.GetType() || typeof(TargetInvocationException) == e.GetType()); + Assert.True(e.Message.Contains("contains") || e.InnerException.Message.Contains("contains")); + } + } + } + + [Fact] + public async Task Order_Entity() + { + var x = await _virtualDbContext.Set().OrderBy(o => o.Money).LastOrDefaultAsync(); + Assert.NotNull(x); + Assert.Equal(319, x.Money); + + var x2 = await _virtualDbContext.Set().Skip(10).OrderBy(o => o.Money).LastOrDefaultAsync(); + Assert.NotNull(x2); + Assert.Equal(319, x2.Money); + + var x3 = await _virtualDbContext.Set().Skip(9999999).OrderBy(o => o.Money).LastOrDefaultAsync(); + Assert.Null(x3); + try + { + var x4 = await _virtualDbContext.Set().Skip(9999999).OrderBy(o => o.Money).LastAsync(); + } + catch (Exception e) + { + Assert.True($"{e}".Contains("Sequence contains no elements.")); + } + + var x1 = await _virtualDbContext.Set().OrderBy(o => o.Money).LastAsync(); + Assert.Equal(x, x1); + var y = await _virtualDbContext.Set().OrderBy(o => o.Money).FirstOrDefaultAsync(); + Assert.NotNull(y); + Assert.Equal(0, y.Money); + var y1 = await _virtualDbContext.Set().OrderBy(o => o.Money).FirstAsync(); + Assert.Equal(y, y1); + var z = await _virtualDbContext.Set().SingleOrDefaultAsync(o => o.Money == 13); + var z1 = await _virtualDbContext.Set().SingleAsync(o => o.Money == 13); + Assert.Equal(z, z1); + } + + [Fact] + public async Task OrderReadWrite() + { + //�л���ֻ�����ݿ⣬ֻ�����ݿ���ֻ������A����Դ��ȡB����Դ + _virtualDbContext.ReadWriteSeparationReadOnly(); + var list = await _virtualDbContext.Set().Where(o => o.Money == 1).ToListAsync(); + Assert.Equal(2, list.Count); + + _virtualDbContext.ReadWriteSeparationWriteOnly(); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("A"); + var areaB = await _virtualDbContext.Set().Where(o => o.Area == "B").FirstOrDefaultAsync(); + Assert.Null(areaB); + } + _virtualDbContext.ReadWriteSeparationReadOnly(); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("A"); + var areaB = await _virtualDbContext.Set().Where(o => o.Area == "B").FirstOrDefaultAsync(); + Assert.NotNull(areaB); + } + + _virtualDbContext.ReadWriteSeparationWriteOnly(); + using (_shardingReadWriteManager.CreateScope()) + { + _shardingReadWriteManager.GetCurrent().SetReadWriteSeparation(100, true); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("A"); + var areaB = await _virtualDbContext.Set().Where(o => o.Area == "B").FirstOrDefaultAsync(); + Assert.NotNull(areaB); + } + } + using (_shardingReadWriteManager.CreateScope()) + { + _shardingReadWriteManager.GetCurrent().SetReadWriteSeparation(100, true); + _virtualDbContext.ReadWriteSeparationWriteOnly(); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("A"); + var areaB = await _virtualDbContext.Set().Where(o => o.Area == "B").FirstOrDefaultAsync(); + Assert.Null(areaB); + } + } + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("A"); + var areaB = await _virtualDbContext.Set().Where(o => o.Area == "B").FirstOrDefaultAsync(); + Assert.Null(areaB); + } + } + + + [Fact] + public async Task LogWeekDateTimeCountTest() + { + var countAsync = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(300, countAsync); + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var fourCount = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).CountAsync(); + Assert.Equal(30, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("20210419_25"); + var countAsync1 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(7, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintTail("20210419_25", "20210426_02"); + var countAsync2 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(14, countAsync2); + } + } + + [Fact] + public async Task LogWeekDateTimeShardingPage() + { + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var page = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(31, page.Total); + + var page1 = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(31, page1.Total); + } + + [Fact] + public async Task LogWeekTimeLongCountTest() + { + var countAsync = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(300, countAsync); + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var fourCount = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).CountAsync(); + Assert.Equal(30, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("20210419_25"); + var countAsync1 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(7, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintTail("20210419_25", "20210426_02"); + var countAsync2 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(14, countAsync2); + } + } + + [Fact] + public async Task LogWeekDateLongShardingPage() + { + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var page = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(31, page.Total); + + var page1 = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(31, page1.Total); + } + + [Fact] + public async Task LogYearTimeLongCountTest() + { + var countAsync = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(600, countAsync); + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var fourCount = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).CountAsync(); + Assert.Equal(30, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("2020"); + var countAsync1 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(366, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintTail("2021"); + var countAsync2 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(234, countAsync2); + } + } + [Fact] + public async Task LogYearDateLongShardingPage() + { + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var page = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(31, page.Total); + + var page1 = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(31, page1.Total); + } + [Fact] + public async Task LogMonthTimeLongCountTest() + { + var countAsync = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(300, countAsync); + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var fourCount = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).CountAsync(); + Assert.Equal(30, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("202104"); + var countAsync1 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(30, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintTail("202104", "202105"); + var countAsync2 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(61, countAsync2); + } + } + [Fact] + public async Task LogMonthDateLongShardingPage() + { + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var page = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(31, page.Total); + + var page1 = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(31, page1.Total); + } + [Fact] + public async Task LogYearLongCountTest() + { + var countAsync = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(300, countAsync); + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var fourCount = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).CountAsync(); + Assert.Equal(30, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("2021"); + var countAsync1 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(300, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + + } + [Fact] + public async Task LogYearLongShardingPage() + { + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var page = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(31, page.Total); + + var page1 = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(31, page1.Total); + } + [Fact] + public async Task CrudTest() + { + var logNoSharding = new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + }; + var logNoShardings = new List() + { + new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + }, + new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + } + + }; + var logNoSharding1 = new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + }; + var logNoSharding1s = new List() + { + new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + }, + new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + } + + }; + using (var tran = await _virtualDbContext.Database.BeginTransactionAsync()) + { + + try + { + await _virtualDbContext.AddAsync(logNoSharding); + + await _virtualDbContext.AddRangeAsync(logNoShardings); + + await _virtualDbContext.Set().AddAsync(logNoSharding1); + + await _virtualDbContext.Set().AddRangeAsync(logNoSharding1s); + await _virtualDbContext.SaveChangesAsync(); + await tran.CommitAsync(); + } + catch (Exception e) + { + await tran.RollbackAsync(); + } + } + logNoSharding.Body = DateTime.Now.ToString("yyyyMMdd"); + _virtualDbContext.Update(logNoSharding); + + logNoShardings.ForEach(o => o.Body = DateTime.Now.ToString("yyyyMMdd")); + _virtualDbContext.UpdateRange(logNoShardings); + + logNoSharding1.Body = DateTime.Now.ToString("yyyyMMdd"); + _virtualDbContext.Set().Update(logNoSharding1); + + logNoSharding1s.ForEach(o => o.Body = DateTime.Now.ToString("yyyyMMdd")); + _virtualDbContext.Set().UpdateRange(logNoSharding1s); + await _virtualDbContext.SaveChangesAsync(); + + + _virtualDbContext.Remove(logNoSharding); + + _virtualDbContext.RemoveRange(logNoShardings); + + _virtualDbContext.Set().Remove(logNoSharding1); + + logNoSharding1s.ForEach(o => o.Body = DateTime.Now.ToString("yyyyMMdd")); + _virtualDbContext.Set().RemoveRange(logNoSharding1s); + await _virtualDbContext.SaveChangesAsync(); + } + [Fact] + public async Task CrudTest1() + { + var logNoSharding = new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + }; + var logNoShardings = new List() + { + new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + }, + new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + } + + }; + using (var tran = await _virtualDbContext.Database.BeginTransactionAsync()) + { + + try + { + await _virtualDbContext.AddAsync((object)logNoSharding); + + await _virtualDbContext.AddRangeAsync(logNoShardings.Select(o => (object)o).ToArray()); + + await _virtualDbContext.SaveChangesAsync(); + await tran.CommitAsync(); + } + catch (Exception e) + { + await tran.RollbackAsync(); + } + } + logNoSharding.Body = DateTime.Now.ToString("yyyyMMdd"); + _virtualDbContext.Update((object)logNoSharding); + + logNoShardings.ForEach(o => o.Body = DateTime.Now.ToString("yyyyMMdd")); + _virtualDbContext.UpdateRange(logNoShardings.Select(o => (object)o).ToArray()); + + await _virtualDbContext.SaveChangesAsync(); + + + _virtualDbContext.Remove((object)logNoSharding); + + _virtualDbContext.RemoveRange(logNoShardings.Select(o => (object)o).ToArray()); + + await _virtualDbContext.SaveChangesAsync(); + } + + + + [Fact] + public async Task Int_ToList_All_Route_Test() + { + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("00"); + + var mod00s = await _virtualDbContext.Set().ToListAsync(); + Assert.Equal(333, mod00s.Count); + } + var mods = await _virtualDbContext.Set().ToListAsync(); + Assert.Equal(1000, mods.Count); + + var modOrders1 = await _virtualDbContext.Set().OrderBy(o => o.Age).ToListAsync(); + int ascAge = 1; + foreach (var sysUserMod in modOrders1) + { + Assert.Equal(ascAge, sysUserMod.Age); + ascAge++; + } + + + var modOrders2 = await _virtualDbContext.Set().OrderByDescending(o => o.Age).ToListAsync(); + int descAge = 1000; + foreach (var sysUserMod in modOrders2) + { + Assert.Equal(descAge, sysUserMod.Age); + descAge--; + } + } + [Fact] + public async Task Int_ToList_All_Test() + { + + var mods = await _virtualDbContext.Set().ToListAsync(); + Assert.Equal(1000, mods.Count); + + var modOrders1 = await _virtualDbContext.Set().OrderBy(o => o.Age).ToListAsync(); + int ascAge = 1; + foreach (var sysUserMod in modOrders1) + { + Assert.Equal(ascAge, sysUserMod.Age); + ascAge++; + } + + var modOrders2 = await _virtualDbContext.Set().OrderByDescending(o => o.Age).ToListAsync(); + int descAge = 1000; + foreach (var sysUserMod in modOrders2) + { + Assert.Equal(descAge, sysUserMod.Age); + descAge--; + } + + + + var pageResult = await _virtualDbContext.Set().Skip(10).Take(10).OrderByDescending(o => o.Age).ToListAsync(); + Assert.Equal(10, pageResult.Count); + int pageDescAge = 990; + foreach (var sysUserMod in pageResult) + { + Assert.Equal(pageDescAge, sysUserMod.Age); + pageDescAge--; + } + } + + + [Fact] + public async Task LogDayLongCountTest() + { + var countAsync = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(3000, countAsync); + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var fourCount = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).CountAsync(); + Assert.Equal(300, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("20210102"); + var countAsync1 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(10, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintTail("20210103", "20210104"); + var countAsync2 = await _virtualDbContext.Set().CountAsync(); + Assert.Equal(20, countAsync2); + } + } + + [Fact] + public async Task LogDayLongShardingPage() + { + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var page = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(300, page.Total); + + var page1 = await _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPageAsync(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(300, page1.Total); + } + + [Fact] + public async Task AsRouteTest() + { + var countAsync3 = await _virtualDbContext.Set().AsRoute(o => + { + o.TryCreateOrAddMustTail("202104"); + }).CountAsync(); + Assert.Equal(30, countAsync3); + var countAsync2 = await _virtualDbContext.Set().AsRoute(o => + { + o.TryCreateOrAddMustTail("2021"); + }).CountAsync(); + Assert.Equal(300, countAsync2); + + var countAsync4 = await _virtualDbContext.Set().AsRoute(o => + { + o.TryCreateOrAddMustTail("20210419_25"); + }).CountAsync(); + Assert.Equal(7, countAsync4); + + var countAsync5 = await _virtualDbContext.Set().AsRoute(o => + { + o.TryCreateOrAddHintTail("20210419_25", "20210426_02"); + }).CountAsync(); + Assert.Equal(14, countAsync5); + + + var fiveBegin = new DateTime(2021, 5, 1).Date; + var sum = await _virtualDbContext.Set().AsRoute(o => + { + o.TryCreateOrAddHintDataSource("C"); + }) + .Where(o => o.CreateTime == fiveBegin).Select(o => o.Money).SumAsync(); + Assert.Equal(0, sum); + } + [Fact] + public async Task QueryInner_Test() + { + var sysUserMods = _virtualDbContext.Set().Select(o => o); + var sysUserModInts = await _virtualDbContext.Set().Where(o => sysUserMods.Select(i => i.Age).Any(i => i == o.Age)).ToListAsync(); + Assert.Equal(1000, sysUserModInts.Count); + } + [Fact] + public async Task Group_API_Test() + { + var ids = new[] { "200", "300" }; + var dateOfMonths = new[] { 202111, 202110 }; + var group = await _virtualDbContext.Set() + .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth)) + .GroupBy(g => new { UId = g.UserId }) + .Select(g => new + { + + GroupUserId = g.Key.UId, + Count = g.Count(), + TotalSalary = g.Sum(o => o.Salary), + AvgSalary = g.Average(o => o.Salary), + AvgSalaryDecimal = g.Average(o => o.SalaryDecimal), + MinSalary = g.Min(o => o.Salary), + MaxSalary = g.Max(o => o.Salary) + }).ToListAsync(); + Assert.Equal(2, group.Count); + Assert.Equal(2, group[0].Count); + Assert.Equal(2260000, group[0].TotalSalary); + Assert.Equal(1130000, group[0].AvgSalary); + Assert.Equal(11300, group[0].AvgSalaryDecimal); + Assert.Equal(1120000, group[0].MinSalary); + Assert.Equal(1140000, group[0].MaxSalary); + } + [Fact] + public async Task Group_API_Test1() + { + var ids = new[] { "200", "300" }; + var dateOfMonths = new[] { 202111, 202110 }; + var group = await _virtualDbContext.Set() + .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth)) + .GroupBy(g => new { UId = g.UserId }) + .Select(g => new + { + + GroupUserId = g.Key.UId, + Count = g.Count(), + TotalSalary = g.Sum(o => o.Salary), + AvgSalary = g.Average(o => o.Salary), + AvgSalaryDecimal = g.Average(o => o.SalaryDecimal), + MinSalary = g.Min(o => o.Salary), + MaxSalary = g.Max(o => o.Salary) + }).OrderBy(o=>o.TotalSalary).ToListAsync(); + Assert.Equal(2, group.Count); + Assert.Equal(2, group[0].Count); + Assert.Equal("200", group[0].GroupUserId); + Assert.Equal(2260000, group[0].TotalSalary); + Assert.Equal(1130000, group[0].AvgSalary); + Assert.Equal(11300, group[0].AvgSalaryDecimal); + Assert.Equal(1120000, group[0].MinSalary); + Assert.Equal(1140000, group[0].MaxSalary); + } + [Fact] + public async Task Group_API_Test2() + { + var ids = new[] { "200", "300" }; + var dateOfMonths = new[] { 202111, 202110 }; + var group = await _virtualDbContext.Set() + .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth)) + .GroupBy(g => new { UId = g.UserId }) + .Select(g => new + { + + GroupUserId = g.Key.UId, + Count = g.Count(), + TotalSalary = g.Sum(o => o.Salary), + AvgSalary = g.Average(o => o.Salary), + AvgSalaryDecimal = g.Average(o => o.SalaryDecimal), + MinSalary = g.Min(o => o.Salary), + MaxSalary = g.Max(o => o.Salary) + }).OrderByDescending(o=>o.TotalSalary).ToListAsync(); + Assert.Equal(2, group.Count); + Assert.Equal(2, group[0].Count); + Assert.Equal("300", group[0].GroupUserId); + Assert.Equal(2690000, group[0].TotalSalary); + Assert.Equal(1345000, group[0].AvgSalary); + Assert.Equal(13450, group[0].AvgSalaryDecimal); + Assert.Equal(1330000, group[0].MinSalary); + Assert.Equal(1360000, group[0].MaxSalary); + } + + [Fact] + public async Task Group_Recently_Test() + { + //var list =(from us in _virtualDbContext.Set().Where(o => ids.Contains(o.UserId)) + // group us by new + // { + // UserId=us.UserId + // } + // into g + // select new + // { + // UserId=g.Key.UserId, + // DateOfMonth = g.Max(o=>o.DateOfMonth) + // }).ToList(); + //var y = list; + + var ids = new List() { "200", "300" }; + List result = new List(ids.Count); + var routeFilter = new List().AsQueryable().Where(o => ids.Contains(o.UserId)); + var dataSourceRouteResult = new DataSourceRouteResult(new HashSet() { _virtualDataSource.DefaultDataSourceName }); + var tableRouteResults = _tableRouteRuleEngineFactory.Route(dataSourceRouteResult, routeFilter,new Dictionary(){{typeof(SysUserSalary),null}}) + .RouteUnits + .Select(o => o.TableRouteResult.ReplaceTables.First().Tail).OrderByDescending(o => o).ToList(); + foreach (var tableRouteResult in tableRouteResults) + { + if (ids.IsEmpty()) + break; + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail(tableRouteResult); + var queryable = _virtualDbContext.Set().Where(o => ids.Contains(o.UserId)) + .GroupBy(o => new { o.UserId }, i => i, + (i, u) => new + { + Data = u.OrderByDescending(o => o.DateOfMonth).FirstOrDefault() + }); + var r = await queryable.ToListAsync(); + result.AddRange(r.Select(o => o.Data)); + var removeUserIds = result.Select(u => u.UserId).ToHashSet(); + ids.RemoveAll(o => removeUserIds.Contains(o)); + } + } + } + } +} \ No newline at end of file diff --git a/src/ShardingCore.Test7x/ShardingTestSync.cs b/src/ShardingCore.Test7x/ShardingTestSync.cs new file mode 100644 index 00000000..3532f625 --- /dev/null +++ b/src/ShardingCore.Test7x/ShardingTestSync.cs @@ -0,0 +1,1541 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Core.QueryRouteManagers.Abstractions; +using ShardingCore.Core.VirtualDatabase.VirtualDataSources; +using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources; +using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions; +using ShardingCore.Exceptions; +using ShardingCore.Extensions; +using ShardingCore.Extensions.ShardingPageExtensions; +using ShardingCore.Helpers; +using ShardingCore.Sharding; +using ShardingCore.Sharding.ParallelTables; +using ShardingCore.Sharding.ReadWriteConfigurations; +using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions; +using ShardingCore.TableCreator; +using ShardingCore.Test.Domain.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using ShardingCore.Core.RuntimeContexts; +using ShardingCore.Core.VirtualRoutes.Abstractions; +using ShardingCore.Extensions.ShardingQueryableExtensions; +using ShardingCore.Sharding.ShardingComparision.Abstractions; +using Xunit; + +namespace ShardingCore.Test +{ + + + public class ShardingTestSync + { + private readonly ShardingDefaultDbContext _virtualDbContext; + private readonly IShardingRouteManager _shardingRouteManager; + private readonly ActualConnectionStringManager _connectionStringManager; + private readonly IConfiguration _configuration; + private readonly IEntityMetadataManager _entityMetadataManager; + private readonly IVirtualDataSource _virtualDataSource; + private readonly ITableRouteManager _tableRouteManager; + private readonly IShardingTableCreator _shardingTableCreator; + private readonly IShardingReadWriteManager _shardingReadWriteManager; + private readonly IRouteTailFactory _routeTailFactory; + private readonly IReadWriteConnectorFactory _readWriteConnectorFactory; + private readonly IShardingConnectionStringResolver _shardingConnectionStringResolver; + private readonly IShardingComparer _shardingComparer; + + public ShardingTestSync(ShardingDefaultDbContext virtualDbContext, IShardingRuntimeContext shardingRuntimeContext, IConfiguration configuration) + { + _virtualDbContext = virtualDbContext; + _shardingRouteManager = shardingRuntimeContext.GetShardingRouteManager(); + _shardingReadWriteManager = shardingRuntimeContext.GetShardingReadWriteManager(); + _virtualDataSource = shardingRuntimeContext.GetVirtualDataSource(); + _connectionStringManager = new ActualConnectionStringManager(_shardingReadWriteManager,_virtualDataSource,virtualDbContext); + _configuration = configuration; + _entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); + _tableRouteManager = shardingRuntimeContext.GetTableRouteManager(); + _shardingTableCreator = shardingRuntimeContext.GetShardingTableCreator(); + _routeTailFactory = shardingRuntimeContext.GetRouteTailFactory(); + _shardingComparer = shardingRuntimeContext.GetShardingComparer(); + _readWriteConnectorFactory = shardingRuntimeContext.GetReadWriteConnectorFactory(); + var readWriteConnectors = _virtualDataSource.ConfigurationParams.ReadWriteNodeSeparationConfigs.Select(o => _readWriteConnectorFactory.CreateConnector(_virtualDataSource.ConfigurationParams.ReadStrategy.GetValueOrDefault(), o.Key, o.Value)); + _shardingConnectionStringResolver = new ReadWriteShardingConnectionStringResolver(readWriteConnectors, _virtualDataSource.ConfigurationParams.ReadStrategy.GetValueOrDefault(),_readWriteConnectorFactory); + } + // [Fact] + // public void RouteParseCompileCacheTest() + // { + // var expressionEqualityComparer = new RouteParseExpressionEqualityComparer(); + // var virtualTable = _virtualTableManager.GetVirtualTable(); + // var virtualTableRoute = (AbstractShardingOperatorVirtualTableRoute)virtualTable.GetVirtualRoute(); + // + // var queryable1 = _virtualDbContext.Set().Where(o => o.DateOfMonth >= 202102); + // var routeParseExpression1 = ShardingUtil.GetRouteParseExpression(queryable1, virtualTableRoute.EntityMetadata, + // (i, op,propertyName) => virtualTableRoute.GetRouteFilter(i, op,propertyName), true); + // var queryable2 = _virtualDbContext.Set().Where(ox => ox.DateOfMonth >= 202102); + // var routeParseExpression2 = ShardingUtil.GetRouteParseExpression(queryable2, virtualTableRoute.EntityMetadata, + // (i, op,propertyName) => virtualTableRoute.GetRouteFilter(i, op,propertyName), true); + // var xxxx1 = 202102; + // var queryable3 = _virtualDbContext.Set().Where(ox => ox.DateOfMonth >= xxxx1); + // var routeParseExpression3 = ShardingUtil.GetRouteParseExpression(queryable3, virtualTableRoute.EntityMetadata, + // (i, op,propertyName) => virtualTableRoute.GetRouteFilter(i, op,propertyName), true); + // var queryable4 = _virtualDbContext.Set().Where(o => o.DateOfMonth >= 202101); + // var routeParseExpression4 = ShardingUtil.GetRouteParseExpression(queryable4, virtualTableRoute.EntityMetadata, + // (i, op,propertyName) => virtualTableRoute.GetRouteFilter(i, op,propertyName), true); + // var queryable5 = _virtualDbContext.Set().Where(o => o.DateOfMonth > 202101); + // var routeParseExpression5 = ShardingUtil.GetRouteParseExpression(queryable5, virtualTableRoute.EntityMetadata, + // (i, op,propertyName) => virtualTableRoute.GetRouteFilter(i, op,propertyName), true); + // var queryable6 = _virtualDbContext.Set().Where(o => o.DateOfMonth == 202101); + // var routeParseExpression6 = ShardingUtil.GetRouteParseExpression(queryable6, virtualTableRoute.EntityMetadata, + // (i, op,propertyName) => virtualTableRoute.GetRouteFilter(i, op,propertyName), true); + // var queryable7 = _virtualDbContext.Set().Where(o => 202101 <= o.DateOfMonth); + // var routeParseExpression7 = ShardingUtil.GetRouteParseExpression(queryable7, virtualTableRoute.EntityMetadata, + // (i, op,propertyName) => virtualTableRoute.GetRouteFilter(i, op,propertyName), true); + // var queryable8 = _virtualDbContext.Set().Where(o => 202101 == o.DateOfMonth); + // var routeParseExpression8 = ShardingUtil.GetRouteParseExpression(queryable8, virtualTableRoute.EntityMetadata, + // (i, op,propertyName) => virtualTableRoute.GetRouteFilter(i, op,propertyName), true); + // Assert.Equal(expressionEqualityComparer.GetHashCode(routeParseExpression1), expressionEqualityComparer.GetHashCode(routeParseExpression2)); + // Assert.Equal(expressionEqualityComparer.GetHashCode(routeParseExpression1), expressionEqualityComparer.GetHashCode(routeParseExpression3)); + // Assert.NotEqual(expressionEqualityComparer.GetHashCode(routeParseExpression1), expressionEqualityComparer.GetHashCode(routeParseExpression4)); + // Assert.Equal(expressionEqualityComparer.GetHashCode(routeParseExpression4), expressionEqualityComparer.GetHashCode(routeParseExpression5)); + // Assert.NotEqual(expressionEqualityComparer.GetHashCode(routeParseExpression5), expressionEqualityComparer.GetHashCode(routeParseExpression6)); + // Assert.Equal(expressionEqualityComparer.GetHashCode(routeParseExpression4), expressionEqualityComparer.GetHashCode(routeParseExpression7)); + // Assert.Equal(expressionEqualityComparer.GetHashCode(routeParseExpression6), expressionEqualityComparer.GetHashCode(routeParseExpression8)); + // + // } + + [Fact] + public void GenericTest() + { + var a = new DefaultPhysicDataSource("aaa", "aaa", true); + var b = new DefaultPhysicDataSource("aaa", "aaa1", false); + Assert.Equal(a, b); + var x = new EntityMetadata(typeof(LogDay)); + //, "aa", typeof(ShardingDefaultDbContext), new List(),null + var y = new EntityMetadata(typeof(LogDay)); + //, "aa1", typeof(ShardingDefaultDbContext), new List(),null + Assert.Equal(x, y); + var dateTime = new DateTime(2021, 1, 1); + var logDays = Enumerable.Range(0, 100).Select(o => new LogDay() { Id = Guid.NewGuid(), LogLevel = "info", LogBody = o.ToString(), LogTime = dateTime.AddDays(o) }).ToList(); + var bulkShardingTableEnumerable = _virtualDbContext.BulkShardingTableEnumerable(logDays); + Assert.Equal(100, bulkShardingTableEnumerable.Count); + var bulkShardingEnumerable = _virtualDbContext.BulkShardingEnumerable(logDays); + Assert.Equal(1, bulkShardingEnumerable.Count); + foreach (var (key, value) in bulkShardingEnumerable) + { + Assert.Equal(100, value.Count); + } + + _virtualDbContext.Set().Where(o => o.Id == "300").ShardingPrint(); + var contains = _virtualDbContext.Set().Where(o => o.Id == "300").Select(o => o.Id).Contains("300"); + Assert.True(contains); + + try + { + var x1 = _virtualDataSource.GetPhysicDataSource("abc"); + } + catch (Exception e) + { + Assert.Equal(typeof(ShardingCoreNotFoundException), e.GetType()); + } + + var queryable = new List().Select(o => new SequenceClass { Id = "123", T = o }).AsQueryable(); + var sourceType = queryable.GetType().GetSequenceType(); + Assert.Equal(typeof(SequenceClass), sourceType); + try + { + _shardingTableCreator.CreateTable("A", "202105"); + } + catch (Exception e) + { + Assert.Equal(typeof(ShardingCoreException), e.GetType()); + } + + var orderMetadata = _entityMetadataManager.TryGet(); + Assert.NotNull(orderMetadata); + var isKey1 = orderMetadata.ShardingDataSourceFieldIsKey(); + Assert.False(isKey1); + var isKey2 = orderMetadata.ShardingTableFieldIsKey(); + Assert.False(isKey2); + var userModMetadata = _entityMetadataManager.TryGet(); + Assert.NotNull(userModMetadata); + var isKey3 = userModMetadata.ShardingDataSourceFieldIsKey(); + Assert.False(isKey3); + var isKey4 = userModMetadata.ShardingTableFieldIsKey(); + Assert.True(isKey4); + + _virtualDbContext.AddRange(logDays); + var bulkShardingExpression = _virtualDbContext.BulkShardingExpression(o => new[] { "A", "B" }.Contains(o.Area)); + Assert.Equal(2, bulkShardingExpression.Count); + Assert.True(bulkShardingExpression.ContainsKey("A")); + Assert.True(bulkShardingExpression.ContainsKey("B")); + + var bulkShardingTableExpression = _virtualDbContext.BulkShardingTableExpression(o => o.Id == Guid.NewGuid().ToString()); + Assert.Equal(1, bulkShardingTableExpression.Count()); + + var isShardingDbContext = _virtualDbContext.IsShardingDbContext(); + Assert.True(isShardingDbContext); + var isShardingTableDbContext = _virtualDbContext.IsShardingTableDbContext(); + Assert.True(isShardingTableDbContext); + var shardingDbContext = _virtualDbContext.GetType().IsShardingDbContext(); + Assert.True(shardingDbContext); + var shardingTableDbContext = _virtualDbContext.GetType().IsShardingTableDbContext(); + Assert.True(shardingTableDbContext); + + var x1x1 = new ParallelTableGroupNode(new HashSet() + { new ParallelTableComparerType(typeof(SysUserMod)), new ParallelTableComparerType(typeof(SysUserSalary)) }); + var x2x2 = new ParallelTableGroupNode(new HashSet() + { new ParallelTableComparerType(typeof(SysUserSalary)),new ParallelTableComparerType(typeof(SysUserMod)), }); + Assert.Equal(x1x1, x2x2); + Assert.Equal(x1x1.GetHashCode(), x2x2.GetHashCode()); + + } + + public class SequenceClass + { + public string Id { get; set; } + public string T { get; set; } + } + + [Fact] + public void TestMultiShardingProperty() + { + + var multiOrder = _virtualDbContext.Set().Where(o => o.Id == 232398109278351360).FirstOrDefault(); + Assert.NotNull(multiOrder); + var longs = new[] { 232398109278351360, 255197859283087360 }; + var multiOrders = _virtualDbContext.Set().Where(o => longs.Contains(o.Id)).ToList(); + Assert.Equal(2, multiOrders.Count); + var dateTime = new DateTime(2021, 11, 1); + var multiOrder404 = _virtualDbContext.Set().Where(o => o.Id == 250345338962063360 && o.CreateTime < dateTime).FirstOrDefault(); + Assert.Null(multiOrder404); + } + [Fact] + public void TestEntityMetadataManager() + { + var objMetadata0 = _entityMetadataManager.TryGet(typeof(object)); + Assert.Null(objMetadata0); + var objMetadata1 = _entityMetadataManager.TryGet(); + Assert.Null(objMetadata1); + + var objMetadata2 = _entityMetadataManager.TryGet(typeof(SysUserMod)); + Assert.NotNull(objMetadata2); + var objMetadata3 = _entityMetadataManager.TryGet(); + Assert.NotNull(objMetadata3); + var sysUserModIsShardingTable0 = _entityMetadataManager.IsShardingTable(typeof(SysUserMod)); + Assert.True(sysUserModIsShardingTable0); + var sysUserModIsShardingTable1 = _entityMetadataManager.IsShardingTable(); + Assert.True(sysUserModIsShardingTable1); + var sysUserModIsShardingDataSource0 = _entityMetadataManager.IsShardingDataSource(typeof(SysUserMod)); + Assert.False(sysUserModIsShardingDataSource0); + var sysUserModIsShardingDataSource1 = _entityMetadataManager.IsShardingDataSource(); + Assert.False(sysUserModIsShardingDataSource1); + } + [Fact] + public void TestShardingComparer() + { + var x = new Guid("7CDE28F8-D548-B96D-1C61-39FFE37AE492"); + var y = new Guid("3425D899-291D-921B-DDE4-49FFE37AE493"); + //asc y 0); + //asc x().Where(o=>o.Id=="339"); + // var routeResults1 = _tableRouteRuleEngineFactory.Route(queryable1); + // Assert.Equal(1,routeResults1.Count()); + // Assert.Equal(1,routeResults1.FirstOrDefault().ReplaceTables.Count()); + // Assert.Equal("0",routeResults1.FirstOrDefault().ReplaceTables.FirstOrDefault().Tail); + // Assert.Equal(nameof(SysUserMod),routeResults1.FirstOrDefault().ReplaceTables.FirstOrDefault().OriginalName); + // var ids = new[] {"339", "124","142"}; + // var queryable2= _virtualDbContext.Set().Where(o=>ids.Contains(o.Id)); + // var routeResult2s = _tableRouteRuleEngineFactory.Route(queryable2); + // Assert.Equal(2,routeResult2s.Count()); + // Assert.Equal(1,routeResult2s.FirstOrDefault().ReplaceTables.Count()); + // Assert.Equal(2,routeResult2s.SelectMany(o=>o.ReplaceTables).Count()); + // Assert.Equal(true,routeResult2s.SelectMany(o=>o.ReplaceTables).All(o=>new[]{"0","1"}.Contains(o.Tail))); + //} + [Fact] + public void ToList_All_Route_Test() + { + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("00"); + + var mod00s = _virtualDbContext.Set().ToList(); + Assert.Equal(333, mod00s.Count); + } + var mods = _virtualDbContext.Set().ToList(); + Assert.Equal(1000, mods.Count); + + var modOrders1 = _virtualDbContext.Set().OrderBy(o => o.Age).ToList(); + int ascAge = 1; + foreach (var sysUserMod in modOrders1) + { + Assert.Equal(ascAge, sysUserMod.Age); + ascAge++; + } + + + var modOrders2 = _virtualDbContext.Set().OrderByDescending(o => o.Age).ToList(); + int descAge = 1000; + foreach (var sysUserMod in modOrders2) + { + Assert.Equal(descAge, sysUserMod.Age); + descAge--; + } + } + [Fact] + public void ToList_All_Test() + { + + var mods = _virtualDbContext.Set().ToList(); + Assert.Equal(1000, mods.Count); + + var modOrders1 = _virtualDbContext.Set().OrderBy(o => o.Age).ToList(); + int ascAge = 1; + foreach (var sysUserMod in modOrders1) + { + Assert.Equal(ascAge, sysUserMod.Age); + ascAge++; + } + + var modOrders2 = _virtualDbContext.Set().OrderByDescending(o => o.Age).ToList(); + int descAge = 1000; + foreach (var sysUserMod in modOrders2) + { + Assert.Equal(descAge, sysUserMod.Age); + descAge--; + } + + + + var pageResult = _virtualDbContext.Set().Skip(10).Take(10).OrderByDescending(o => o.Age).ToList(); + Assert.Equal(10, pageResult.Count); + int pageDescAge = 990; + foreach (var sysUserMod in pageResult) + { + Assert.Equal(pageDescAge, sysUserMod.Age); + pageDescAge--; + } + var skip10First = _virtualDbContext.Set().Skip(10).OrderByDescending(o => o.Age).FirstOrDefault(); + Assert.Equal(skip10First, pageResult[0]); + } + + [Fact] + public void ToList_Join_Test() + { + var list = (from u in _virtualDbContext.Set() + join salary in _virtualDbContext.Set() + on u.Id equals salary.UserId + select new + { + u.Id, + u.Age, + Salary = salary.Salary, + DateOfMonth = salary.DateOfMonth, + Name = u.Name + }).ToList(); + + var list2 = list.OrderBy(o => o.Age).Select(o => o.Age).Distinct().ToList(); + Assert.Equal(24000, list.Count()); + Assert.Equal(24, list.Count(o => o.Name == "name_200")); + + + var queryable = (from u in _virtualDbContext.Set().Where(o => o.Id == "300") + join salary in _virtualDbContext.Set() + on u.Id equals salary.UserId + select new + { + Salary = salary.Salary, + DateOfMonth = salary.DateOfMonth, + Name = u.Name + }); + var list1 = queryable.ToList(); + Assert.Equal(24, list1.Count()); + Assert.DoesNotContain(list1, o => o.Name != "name_300"); + + var queryable1 = (from u in _virtualDbContext.Set().Where(o => o.Id == "300") + join salary in _virtualDbContext.Set().Where(o => o.DateOfMonth == 202005) + on u.Id equals salary.UserId + select new + { + Salary = salary.Salary, + DateOfMonth = salary.DateOfMonth, + Name = u.Name + }); + var list3 = queryable1.ToList(); + Assert.Equal(1, list3.Count()); + Assert.Contains(list3, o => o.Name == "name_300"); + } + + [Fact] + public void ToList_OrderBy_Asc_Desc_Test() + { + var modascs = _virtualDbContext.Set().OrderBy(o => o.Age).ToList(); + Assert.Equal(1000, modascs.Count); + var i = 1; + foreach (var age in modascs) + { + Assert.Equal(i, age.Age); + i++; + } + + var moddescs = _virtualDbContext.Set().OrderByDescending(o => o.Age).ToList(); + Assert.Equal(1000, moddescs.Count); + var j = 1000; + foreach (var age in moddescs) + { + Assert.Equal(j, age.Age); + j--; + } + } + + [Fact] + public void ToList_Id_In_Test() + { + var ids = new[] { "1", "2", "3", "4" }; + var sysUserMods = _virtualDbContext.Set().Where(o => new List { "1", "2", "3", "4" }.Contains(o.Id)).ToList(); + foreach (var id in ids) + { + Assert.Contains(sysUserMods, o => o.Id == id); + } + + Assert.DoesNotContain(sysUserMods, o => o.Age > 4); + } + + [Fact] + public void ToList_Id_Eq_Test() + { + var id = 3; + var mods = _virtualDbContext.Set().Where(o => o.Id == id.ToString()).ToList(); + Assert.Single(mods); + var mods1 = _virtualDbContext.Set().Where(o => o.Id == "4").ToList(); + Assert.Single(mods1); + Assert.Equal("3", mods[0].Id); + } + + [Fact] + public void ToList_Id_Not_Eq_Test() + { + var mods = _virtualDbContext.Set().Where(o => o.Id != "3").ToList(); + Assert.Equal(999, mods.Count); + Assert.DoesNotContain(mods, o => o.Id == "3"); + } + + [Fact] + public void ToList_Id_Not_Eq_Skip_Test() + { + var mods = _virtualDbContext.Set().Where(o => o.Id != "3").OrderBy(o => o.Age).Skip(2).ToList(); + Assert.Equal(997, mods.Count); + Assert.DoesNotContain(mods, o => o.Id == "3"); + Assert.Equal(4, mods[0].Age); + Assert.Equal(5, mods[1].Age); + + var modsDesc = _virtualDbContext.Set().Where(o => o.Id != "3").OrderByDescending(o => o.Age).Skip(13).ToList(); + Assert.Equal(986, modsDesc.Count); + Assert.DoesNotContain(mods, o => o.Id == "3"); + Assert.Equal(987, modsDesc[0].Age); + Assert.Equal(986, modsDesc[1].Age); + } + + [Fact] + public void ToList_Name_Eq_Test() + { + var mods = _virtualDbContext.Set().Where(o => o.Name == "name_3").ToList(); + Assert.Single(mods); + Assert.Equal("3", mods[0].Id); + } + + [Fact] + public void ToList_Id_Eq_Not_In_Db_Test() + { + var mods = _virtualDbContext.Set().Where(o => o.Id == "1001").ToList(); + Assert.Empty(mods); + } + + [Fact] + public void ToList_Name_Eq_Not_In_Db_Test() + { + var mods = _virtualDbContext.Set().Where(o => o.Name == "name_1001").ToList(); + Assert.Empty(mods); + } + + [Fact] + public void FirstOrDefault_Order_By_Id_Test() + { + var sysUserModAge = _virtualDbContext.Set().OrderBy(o => o.Age).FirstOrDefault(); + Assert.True(sysUserModAge != null && sysUserModAge.Id == "1"); + var sysUserModAgeDesc = _virtualDbContext.Set().OrderByDescending(o => o.Age).FirstOrDefault(); + Assert.True(sysUserModAgeDesc != null && sysUserModAgeDesc.Id == "1000"); + var sysUserMod = _virtualDbContext.Set().OrderBy(o => o.Id).FirstOrDefault(); + Assert.True(sysUserMod != null && sysUserMod.Id == "1"); + + var sysUserModDesc = _virtualDbContext.Set().OrderByDescending(o => o.Id).FirstOrDefault(); + Assert.True(sysUserModDesc != null && sysUserModDesc.Id == "999"); + + } + + [Fact] + public void FirstOrDefault2() + { + + var x = new Object[] { "1", "2" }; + var sysUserModab = _virtualDbContext.Set().Where(o => o.Id.Equals("1")).FirstOrDefault(); + Assert.NotNull(sysUserModab); + Assert.True(sysUserModab.Id == "1"); + var sysUserModaa = _virtualDbContext.Set().Where(o => "1".Equals(o.Id)).FirstOrDefault(); + Assert.NotNull(sysUserModaa); + Assert.True(sysUserModaa.Id == "1"); + var sysUserMod = _virtualDbContext.Set().Where(o => o.Id == "1").FirstOrDefault(); + Assert.NotNull(sysUserMod); + Assert.True(sysUserMod.Id == "1"); + var sysUserModxx = _virtualDbContext.Set().Where(o => x.Contains(o.Id)).FirstOrDefault(); + Assert.NotNull(sysUserModxx); + Assert.Equal(sysUserModaa, sysUserMod); + Assert.True(x.Contains(sysUserModxx.Id)); + Assert.NotNull(sysUserMod); + var userMod = _virtualDbContext.Set().Find("1"); + Assert.Equal(sysUserMod, userMod); + Assert.True(sysUserMod.Id == "1"); + var user198 = _virtualDbContext.Set().FirstOrDefault(o => o.Id == "198"); + Assert.True(user198.Id == "198"); + var userId198 = _virtualDbContext.Set().Where(o => o.Id == "198").Select(o => o.Id).FirstOrDefault(); + Assert.Equal(userId198, "198"); + + } + + [Fact] + public void FirstOrDefault3() + { + var sysUserMod = _virtualDbContext.Set().Where(o => o.Name == "name_2").FirstOrDefault(); + Assert.NotNull(sysUserMod); + Assert.Equal("2", sysUserMod.Id); + + } + + [Fact] + public void FirstOrDefault4() + { + var sysUserMod = _virtualDbContext.Set().Where(o => o.Id != "1").FirstOrDefault(); + Assert.NotNull(sysUserMod); + Assert.True(sysUserMod.Id != "1"); + } + + [Fact] + public void FirstOrDefault5() + { + var sysUserMod = _virtualDbContext.Set().Where(o => o.Name == "name_1001").FirstOrDefault(); + Assert.Null(sysUserMod); + } + + [Fact] + public void Count_Test() + { + var a = _virtualDbContext.Set().Where(o => o.Name == "name_1000").Count(); + Assert.Equal(1, a); + var b = _virtualDbContext.Set().Where(o => o.Name != "name_1000").Count(); + Assert.Equal(999, b); + } + + [Fact] + public void Sum_Test() + { + var a = _virtualDbContext.Set().Sum(o => o.Age); + var expected = 0; + for (int i = 1; i <= 1000; i++) + { + expected += i; + } + + Assert.Equal(expected, a); + var b = _virtualDbContext.Set().Where(o => o.Name != "name_1000").Sum(o => o.Age); + Assert.Equal(expected - 1000, b); + } + + [Fact] + public void Max_Test() + { + var a = _virtualDbContext.Set().Max(o => o.Age); + Assert.Equal(1000, a); + var b = _virtualDbContext.Set().Where(o => o.Name != "name_1000").Max(o => o.Age); + Assert.Equal(999, b); + var c = _virtualDbContext.Set().Where(o => o.Age < 500).Max(o => o.Age); + Assert.Equal(499, c); + var e = _virtualDbContext.Set().Where(o => o.Age <= 500).Max(o => o.Age); + Assert.Equal(500, e); + } + + [Fact] + public void Max_Join_Test() + { + var queryable = (from u in _virtualDbContext.Set().Where(o => o.Id == "300") + join salary in _virtualDbContext.Set() + on u.Id equals salary.UserId + select new + { + Salary = salary.Salary, + DateOfMonth = salary.DateOfMonth, + Name = u.Name + }); + var maxSalary = queryable.Max(o => o.Salary); + Assert.Equal(1390000, maxSalary); + } + + [Fact] + public void Min_Test() + { + var a = _virtualDbContext.Set().Min(o => o.Age); + Assert.Equal(1, a); + var b = _virtualDbContext.Set().Where(o => o.Name != "name_1").Min(o => o.Age); + Assert.Equal(2, b); + var c = _virtualDbContext.Set().Where(o => o.Age > 500).Min(o => o.Age); + Assert.Equal(501, c); + var e = _virtualDbContext.Set().Where(o => o.Age >= 500).Min(o => o.Age); + Assert.Equal(500, e); + } + + [Fact] + public void Any_Test() + { + var a = _virtualDbContext.Set().Any(o => o.Age == 100); + Assert.True(a); + var b = _virtualDbContext.Set().Where(o => o.Name != "name_1").Any(o => o.Age == 1); + Assert.False(b); + var c = _virtualDbContext.Set().Where(o => o.Age > 500).Any(o => o.Age <= 500); + Assert.False(c); + var e = _virtualDbContext.Set().Where(o => o.Age >= 500).Any(o => o.Age <= 500); + Assert.True(e); + } + + [Fact] + public void Group_Test() + { + var ids = new[] { "200", "300" }; + var dateOfMonths = new[] { 202111, 202110 }; + var group = (from u in _virtualDbContext.Set() + .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth)) + group u by new + { + UId = u.UserId + } + into g + select new + { + GroupUserId = g.Key.UId, + Count = g.Count(), + TotalSalary = g.Sum(o => o.Salary), + AvgSalary = g.Average(o => o.Salary), + AvgSalaryDecimal = g.Average(o => o.SalaryDecimal), + MinSalary = g.Min(o => o.Salary), + MaxSalary = g.Max(o => o.Salary) + }).ToList(); + Assert.Equal(2, group.Count); + Assert.Equal(2, group[0].Count); + Assert.Equal(2260000, group[0].TotalSalary); + Assert.Equal(1130000, group[0].AvgSalary); + Assert.Equal(11300, group[0].AvgSalaryDecimal); + Assert.Equal(1120000, group[0].MinSalary); + Assert.Equal(1140000, group[0].MaxSalary); + } + + [Fact] + public void OrderCountTest() + { + var asyncCount = _virtualDbContext.Set().Count(); + Assert.Equal(320, asyncCount); + var syncCount = _virtualDbContext.Set().Count(); + Assert.Equal(320, syncCount); + + var countA = _virtualDbContext.Set().Count(o => o.Area == "A"); + var countB = _virtualDbContext.Set().Count(o => o.Area == "B"); + var countC = _virtualDbContext.Set().Count(o => o.Area == "C"); + Assert.Equal(320, countA + countB + countC); + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var fourCount = _virtualDbContext.Set().Where(o => o.CreateTime >= fourBegin && o.CreateTime < fiveBegin).Count(); + Assert.Equal(30, fourCount); + } + [Fact] + public void OrderFirstTest() + { + var threeMonth = new DateTime(2021, 3, 1); + var order = _virtualDbContext.Set().FirstOrDefault(o => o.CreateTime == threeMonth);//第59条 1月31天2月28天 + Assert.NotNull(order); + Assert.Equal(59, order.Money); + Assert.Equal("C", order.Area); + } + [Fact] + public void OrderOrderTest() + { + var orders = _virtualDbContext.Set().OrderBy(o => o.CreateTime).ToList(); + Assert.Equal(320, orders.Count); + var i = 0; + foreach (var order in orders) + { + Assert.Equal(i, order.Money); + i++; + } + + var threeMonth = new DateTime(2021, 3, 1); + var orderPage = _virtualDbContext.Set().Where(o => o.CreateTime > threeMonth).OrderByDescending(o => o.CreateTime).ToShardingPage(1, 20); + Assert.Equal(20, orderPage.Data.Count); + Assert.Equal(260, orderPage.Total); + + var j = 319; + foreach (var order in orderPage.Data) + { + Assert.Equal(j, order.Money); + j--; + } + } + + [Fact] + public void LogDayCountTest() + { + var countAsync = _virtualDbContext.Set().Count(); + Assert.Equal(3000, countAsync); + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var fourCount = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).Count(); + Assert.Equal(300, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("20210102"); + var countAsync1 = _virtualDbContext.Set().Count(); + Assert.Equal(10, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintTail("20210103", "20210104"); + var countAsync2 = _virtualDbContext.Set().Count(); + Assert.Equal(20, countAsync2); + } + } + [Fact] + public void LogDayTableSeparatorTest() + { + var virtualTableRoute = _tableRouteManager.GetRoute(typeof(LogDay)); + var virtualTableName = virtualTableRoute.EntityMetadata.LogicTableName; + Assert.Equal(nameof(LogDay), virtualTableName); + Assert.True(string.IsNullOrWhiteSpace(virtualTableRoute.EntityMetadata.TableSeparator)); + var entityMetadata = _entityMetadataManager.TryGet(); + Assert.NotNull(entityMetadata); + var isShardingTable = entityMetadata.IsShardingTable(); + Assert.True(isShardingTable); + var isShardingDataSource = entityMetadata.IsShardingDataSource(); + Assert.False(isShardingDataSource); + var emptySeparator = string.IsNullOrWhiteSpace(entityMetadata.TableSeparator); + Assert.True(emptySeparator); + Assert.Null(entityMetadata.AutoCreateDataSourceTable); + } + + [Fact] + public void LogDayShardingPage() + { + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var page = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPage(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(300, page.Total); + + var page1 = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPage(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(300, page1.Total); + + } + + [Fact] + public void Order_Average() + { + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var moneyAverage = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => o.Money).Average(); + Assert.Equal(105, moneyAverage); + + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("C"); + var sum = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => o.Money).Sum(); + Assert.Equal(0, sum); + var sum1 = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (long?)o.Money).Sum(); + Assert.Equal(0, sum1); + var sum2 = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (int)o.Money).Sum(); + Assert.Equal(0, sum2); + var sum3 = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (int?)o.Money).Sum(); + Assert.Equal(0, sum3); + var sum4 = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (decimal)o.Money).Sum(); + Assert.Equal(0, sum4); + var sum5 = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (decimal?)o.Money).Sum(); + Assert.Equal(0, sum5); + var sum6 = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (double)o.Money).Sum(); + Assert.Equal(0, sum6); + var sum7 = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (double?)o.Money).Sum(); + Assert.Equal(0, sum7); + var sum8 = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (float)o.Money).Sum(); + Assert.Equal(0, sum8); + var sum9 = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => (float?)o.Money).Sum(); + Assert.Equal(0, sum9); + } + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintDataSource("C"); + var sum = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => o.Money).Sum(); + Assert.Equal(0, sum); + } + + var all = _virtualDbContext.Set().All(o => o.Money <= 321); + Assert.True(all); + var longCount = _virtualDbContext.Set().LongCount(); + Assert.Equal(320, longCount); + } + + [Fact] + public void Order_Max() + { + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var moneyMax = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => o.Money).Max(); + Assert.Equal(120, moneyMax); + var moneyMax1 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (long?)o.Money).Max(); + Assert.Equal(120, moneyMax1); + var moneyMax2 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (int)o.Money).Max(); + Assert.Equal(120, moneyMax2); + var moneyMax3 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (int?)o.Money).Max(); + Assert.Equal(120, moneyMax3); + var moneyMax4 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (double)o.Money).Max(); + Assert.Equal(120, moneyMax4); + var moneyMax5 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (double?)o.Money).Max(); + Assert.Equal(120, moneyMax5); + var moneyMax6 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (float)o.Money).Max(); + Assert.Equal(120, moneyMax6); + var moneyMax7 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (float?)o.Money).Max(); + Assert.Equal(120, moneyMax7); + var moneyMax8 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (decimal)o.Money).Max(); + Assert.Equal(120, moneyMax8); + var moneyMax9 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (decimal?)o.Money).Max(); + Assert.Equal(120, moneyMax9); + + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("C"); + try + { + var max = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => o.Money).Max(); + } + catch (Exception e) + { + Assert.True(typeof(InvalidOperationException) == e.GetType() || typeof(TargetInvocationException) == e.GetType()); + Assert.True(e.Message.Contains("contains")|| e.InnerException.Message.Contains("contains")); + } + } + } + [Fact] + public void Order_Min() + { + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var moneyMin = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => o.Money).Min(); + Assert.Equal(90, moneyMin); + var moneyMin1 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (long?)o.Money).Min(); + Assert.Equal(90, moneyMin1); + var moneyMin2 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (int)o.Money).Min(); + Assert.Equal(90, moneyMin2); + var moneyMin3 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (int?)o.Money).Min(); + Assert.Equal(90, moneyMin3); + var moneyMin4 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (float)o.Money).Min(); + Assert.Equal(90, moneyMin4); + var moneyMin5 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (float?)o.Money).Min(); + Assert.Equal(90, moneyMin5); + var moneyMin6 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (double)o.Money).Min(); + Assert.Equal(90, moneyMin6); + var moneyMin7 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (double?)o.Money).Min(); + Assert.Equal(90, moneyMin7); + var moneyMin8 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (decimal)o.Money).Min(); + Assert.Equal(90, moneyMin8); + var moneyMin9 = _virtualDbContext.Set() + .Where(o => o.CreateTime >= fourBegin && o.CreateTime <= fiveBegin).Select(o => (decimal?)o.Money).Min(); + Assert.Equal(90, moneyMin9); + + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("C"); + try + { + var max = _virtualDbContext.Set() + .Where(o => o.CreateTime == fiveBegin).Select(o => o.Money).Min(); + } + catch (Exception e) + { + Assert.True(typeof(InvalidOperationException) == e.GetType() || typeof(TargetInvocationException) == e.GetType()); + Assert.True(e.Message.Contains("contains") || e.InnerException.Message.Contains("contains")); + } + } + } + + [Fact] + public void Order_Entity() + { + var x = _virtualDbContext.Set().OrderBy(o => o.Money).LastOrDefault(); + Assert.NotNull(x); + Assert.Equal(319, x.Money); + var x1 = _virtualDbContext.Set().OrderBy(o => o.Money).Last(); + Assert.Equal(x, x1); + var y = _virtualDbContext.Set().OrderBy(o => o.Money).FirstOrDefault(); + Assert.NotNull(y); + Assert.Equal(0, y.Money); + var y1 = _virtualDbContext.Set().OrderBy(o => o.Money).First(); + Assert.Equal(y, y1); + var z = _virtualDbContext.Set().SingleOrDefault(o => o.Money == 13); + var z1 = _virtualDbContext.Set().Single(o => o.Money == 13); + Assert.Equal(z, z1); + } + [Fact] + public void OrderReadWrite() + { + //切换到只读数据库,只读数据库又只配置了A数据源读取B数据源 + _virtualDbContext.ReadWriteSeparationReadOnly(); + var list = _virtualDbContext.Set().Where(o => o.Money == 1).ToList(); + Assert.Equal(2, list.Count); + + _virtualDbContext.ReadWriteSeparationWriteOnly(); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("A"); + var areaB = _virtualDbContext.Set().Where(o => o.Area == "B").FirstOrDefault(); + Assert.Null(areaB); + } + _virtualDbContext.ReadWriteSeparationReadOnly(); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("A"); + var areaB = _virtualDbContext.Set().Where(o => o.Area == "B").FirstOrDefault(); + Assert.NotNull(areaB); + } + _virtualDbContext.ReadWriteSeparationWriteOnly(); + using (_shardingReadWriteManager.CreateScope()) + { + _shardingReadWriteManager.GetCurrent().SetReadWriteSeparation(100, true); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("A"); + var areaB = _virtualDbContext.Set().Where(o => o.Area == "B").FirstOrDefault(); + Assert.NotNull(areaB); + } + } + using (_shardingReadWriteManager.CreateScope()) + { + _shardingReadWriteManager.GetCurrent().SetReadWriteSeparation(100, true); + _virtualDbContext.ReadWriteSeparationWriteOnly(); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("A"); + var areaB = _virtualDbContext.Set().Where(o => o.Area == "B").FirstOrDefault(); + Assert.Null(areaB); + } + } + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustDataSource("A"); + var areaB = _virtualDbContext.Set().Where(o => o.Area == "B").FirstOrDefault(); + Assert.Null(areaB); + } + } + [Fact] + public void LogWeekDateTimeCountTest() + { + var countAsync = _virtualDbContext.Set().Count(); + Assert.Equal(300, countAsync); + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var fourCount = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).Count(); + Assert.Equal(30, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("20210419_25"); + var countAsync1 = _virtualDbContext.Set().Count(); + Assert.Equal(7, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintTail("20210419_25", "20210426_02"); + var countAsync2 = _virtualDbContext.Set().Count(); + Assert.Equal(14, countAsync2); + } + } + + [Fact] + public void LogWeekDateTimeShardingPage() + { + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var page = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPage(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(31, page.Total); + + var page1 = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPage(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(31, page1.Total); + } + + [Fact] + public void LogWeekTimeLongCountTest() + { + var countAsync = _virtualDbContext.Set().Count(); + Assert.Equal(300, countAsync); + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var fourCount = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).Count(); + Assert.Equal(30, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("20210419_25"); + var countAsync1 = _virtualDbContext.Set().Count(); + Assert.Equal(7, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintTail("20210419_25", "20210426_02"); + var countAsync2 = _virtualDbContext.Set().Count(); + Assert.Equal(14, countAsync2); + } + } + + [Fact] + public void LogWeekDateLongShardingPage() + { + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var page = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPage(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(31, page.Total); + + var page1 = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPage(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(31, page1.Total); + } + [Fact] + public void LogYearTimeLongCountTest() + { + var countAsync = _virtualDbContext.Set().Count(); + Assert.Equal(600, countAsync); + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var fourCount = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).Count(); + Assert.Equal(30, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("2020"); + var countAsync1 = _virtualDbContext.Set().Count(); + Assert.Equal(366, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintTail("2021"); + var countAsync2 = _virtualDbContext.Set().Count(); + Assert.Equal(234, countAsync2); + } + } + [Fact] + public void LogYearDateLongShardingPage() + { + var fourBegin = new DateTime(2021, 4, 1).Date; + var fiveBegin = new DateTime(2021, 5, 1).Date; + var page = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPage(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(31, page.Total); + + var page1 = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPage(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(31, page1.Total); + } + + [Fact] + public void LogMonthTimeLongCountTest() + { + var countAsync = _virtualDbContext.Set().Count(); + Assert.Equal(300, countAsync); + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var fourCount = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).Count(); + Assert.Equal(30, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("202104"); + var countAsync1 = _virtualDbContext.Set().Count(); + Assert.Equal(30, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintTail("202104", "202105"); + var countAsync2 = _virtualDbContext.Set().Count(); + Assert.Equal(61, countAsync2); + } + } + [Fact] + public void LogMonthDateLongShardingPage() + { + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var page = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPage(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(31, page.Total); + + var page1 = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPage(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(31, page1.Total); + } + [Fact] + public async Task LogYearLongCountTest() + { + var countAsync = _virtualDbContext.Set().Count(); + Assert.Equal(300, countAsync); + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var fourCount = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).Count(); + Assert.Equal(30, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("2021"); + var countAsync1 = _virtualDbContext.Set().Count(); + Assert.Equal(300, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + } + [Fact] + public async Task LogYearLongShardingPage() + { + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var page = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPage(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(31, page.Total); + + var page1 = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPage(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(31, page1.Total); + } + + [Fact] + public void CrudTest() + { + var logNoSharding = new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + }; + var logNoShardings = new List() + { + new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + }, + new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + } + + }; + var logNoSharding1 = new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + }; + var logNoSharding1s = new List() + { + new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + }, + new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + } + + }; + using (var tran = _virtualDbContext.Database.BeginTransaction()) + { + + try + { + _virtualDbContext.Add(logNoSharding); + + _virtualDbContext.AddRange(logNoShardings); + + _virtualDbContext.Set().Add(logNoSharding1); + + _virtualDbContext.Set().AddRange(logNoSharding1s); + _virtualDbContext.SaveChanges(); + tran.Commit(); + } + catch (Exception e) + { + tran.Rollback(); + } + } + logNoSharding.Body = DateTime.Now.ToString("yyyyMMdd"); + _virtualDbContext.Update(logNoSharding); + + logNoShardings.ForEach(o => o.Body = DateTime.Now.ToString("yyyyMMdd")); + _virtualDbContext.UpdateRange(logNoShardings); + + logNoSharding1.Body = DateTime.Now.ToString("yyyyMMdd"); + _virtualDbContext.Set().Update(logNoSharding1); + + logNoSharding1s.ForEach(o => o.Body = DateTime.Now.ToString("yyyyMMdd")); + _virtualDbContext.Set().UpdateRange(logNoSharding1s); + _virtualDbContext.SaveChanges(); + + + _virtualDbContext.Remove(logNoSharding); + + _virtualDbContext.RemoveRange(logNoShardings); + + _virtualDbContext.Set().Remove(logNoSharding1); + + logNoSharding1s.ForEach(o => o.Body = DateTime.Now.ToString("yyyyMMdd")); + _virtualDbContext.Set().RemoveRange(logNoSharding1s); + _virtualDbContext.SaveChanges(); + } + [Fact] + public void CrudTest1() + { + var logNoSharding = new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + }; + var logNoShardings = new List() + { + new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + }, + new LogNoSharding() + { + Id = Guid.NewGuid().ToString("n"), + Body = DateTime.Now.ToString("yyyyMMddHHmmss"), + CreationTime = DateTime.Now + } + + }; + using (var tran = _virtualDbContext.Database.BeginTransaction()) + { + + try + { + _virtualDbContext.Add((object)logNoSharding); + + _virtualDbContext.AddRange(logNoShardings.Select(o => (object)o).ToArray()); + + _virtualDbContext.SaveChanges(); + tran.Commit(); + } + catch (Exception e) + { + tran.Rollback(); + } + } + } + + + [Fact] + public void Int_ToList_All_Route_Test() + { + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("00"); + + var mod00s = _virtualDbContext.Set().ToList(); + Assert.Equal(333, mod00s.Count); + } + var mods = _virtualDbContext.Set().ToList(); + Assert.Equal(1000, mods.Count); + + var modOrders1 = _virtualDbContext.Set().OrderBy(o => o.Age).ToList(); + int ascAge = 1; + foreach (var sysUserMod in modOrders1) + { + Assert.Equal(ascAge, sysUserMod.Age); + ascAge++; + } + + + var modOrders2 = _virtualDbContext.Set().OrderByDescending(o => o.Age).ToList(); + int descAge = 1000; + foreach (var sysUserMod in modOrders2) + { + Assert.Equal(descAge, sysUserMod.Age); + descAge--; + } + } + [Fact] + public void Int_ToList_All_Test() + { + + var mods = _virtualDbContext.Set().ToList(); + Assert.Equal(1000, mods.Count); + + var modOrders1 = _virtualDbContext.Set().OrderBy(o => o.Age).ToList(); + int ascAge = 1; + foreach (var sysUserMod in modOrders1) + { + Assert.Equal(ascAge, sysUserMod.Age); + ascAge++; + } + + var modOrders2 = _virtualDbContext.Set().OrderByDescending(o => o.Age).ToList(); + int descAge = 1000; + foreach (var sysUserMod in modOrders2) + { + Assert.Equal(descAge, sysUserMod.Age); + descAge--; + } + + + + var pageResult = _virtualDbContext.Set().Skip(10).Take(10).OrderByDescending(o => o.Age).ToList(); + Assert.Equal(10, pageResult.Count); + int pageDescAge = 990; + foreach (var sysUserMod in pageResult) + { + Assert.Equal(pageDescAge, sysUserMod.Age); + pageDescAge--; + } + } + + + [Fact] + public void LogDayLongCountTest() + { + var countAsync = _virtualDbContext.Set().Count(); + Assert.Equal(3000, countAsync); + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var fourCount = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime < fiveBegin).Count(); + Assert.Equal(300, fourCount); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddMustTail("20210102"); + var countAsync1 = _virtualDbContext.Set().Count(); + Assert.Equal(10, countAsync1); + } + Assert.Null(_shardingRouteManager.Current); + using (_shardingRouteManager.CreateScope()) + { + _shardingRouteManager.Current.TryCreateOrAddHintTail("20210103", "20210104"); + var countAsync2 = _virtualDbContext.Set().Count(); + Assert.Equal(20, countAsync2); + } + } + + [Fact] + public void LogDayLongShardingPage() + { + var fourBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 4, 1).Date); + var fiveBegin = ShardingCoreHelper.ConvertDateTimeToLong(new DateTime(2021, 5, 1).Date); + var page = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin).OrderBy(o => o.LogTime) + .ToShardingPage(2, 10); + Assert.Equal(10, page.Data.Count); + Assert.Equal(300, page.Total); + + var page1 = _virtualDbContext.Set().Where(o => o.LogTime >= fourBegin && o.LogTime <= fiveBegin) + .ToShardingPage(2, 10); + Assert.Equal(10, page1.Data.Count); + Assert.Equal(300, page1.Total); + } + [Fact] + public void AsRouteTest() + { + var countAsync3 = _virtualDbContext.Set().AsRoute(o => + { + o.TryCreateOrAddMustTail("202104"); + }).Count(); + Assert.Equal(30, countAsync3); + var countAsync2 = _virtualDbContext.Set().AsRoute(o => + { + o.TryCreateOrAddMustTail("2021"); + }).Count(); + Assert.Equal(300, countAsync2); + + var countAsync4 = _virtualDbContext.Set().AsRoute(o => + { + o.TryCreateOrAddMustTail("20210419_25"); + }).Count(); + Assert.Equal(7, countAsync4); + + var countAsync5 = _virtualDbContext.Set().AsRoute(o => + { + o.TryCreateOrAddHintTail("20210419_25", "20210426_02"); + }).Count(); + Assert.Equal(14, countAsync5); + + + var fiveBegin = new DateTime(2021, 5, 1).Date; + var sum = _virtualDbContext.Set().AsRoute(o => + { + o.TryCreateOrAddHintDataSource("C"); + }) + .Where(o => o.CreateTime == fiveBegin).Select(o => o.Money).Sum(); + Assert.Equal(0, sum); + } + [Fact] + public void QueryInner_Test() + { + var sysUserMods = _virtualDbContext.Set().Select(o => o); + var sysUserModInts = _virtualDbContext.Set().Where(o => sysUserMods.Select(i => i.Age).Any(i => i == o.Age)).ToList(); + Assert.Equal(1000, sysUserModInts.Count); + } + [Fact] + public void Group_API_Test() + { + var ids = new[] { "200", "300" }; + var dateOfMonths = new[] { 202111, 202110 }; + var group = _virtualDbContext.Set() + .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth)) + .GroupBy(g => new { UId = g.UserId }) + .Select(g => new + { + + GroupUserId = g.Key.UId, + Count = g.Count(), + TotalSalary = g.Sum(o => o.Salary), + AvgSalary = g.Average(o => o.Salary), + AvgSalaryDecimal = g.Average(o => o.SalaryDecimal), + MinSalary = g.Min(o => o.Salary), + MaxSalary = g.Max(o => o.Salary) + }).ToList(); + Assert.Equal(2, group.Count); + Assert.Equal(2, group[0].Count); + Assert.Equal(2260000, group[0].TotalSalary); + Assert.Equal(1130000, group[0].AvgSalary); + Assert.Equal(11300, group[0].AvgSalaryDecimal); + Assert.Equal(1120000, group[0].MinSalary); + Assert.Equal(1140000, group[0].MaxSalary); + } + [Fact] + public void Group_API_Test1() + { + var ids = new[] { "200", "300" }; + var dateOfMonths = new[] { 202111, 202110 }; + var group = _virtualDbContext.Set() + .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth)) + .GroupBy(g => new { UId = g.UserId }) + .Select(g => new + { + + GroupUserId = g.Key.UId, + Count = g.Count(), + TotalSalary = g.Sum(o => o.Salary), + AvgSalary = g.Average(o => o.Salary), + AvgSalaryDecimal = g.Average(o => o.SalaryDecimal), + MinSalary = g.Min(o => o.Salary), + MaxSalary = g.Max(o => o.Salary) + }).OrderBy(o => o.TotalSalary).ToList(); + Assert.Equal(2, group.Count); + Assert.Equal(2, group[0].Count); + Assert.Equal("200", group[0].GroupUserId); + Assert.Equal(2260000, group[0].TotalSalary); + Assert.Equal(1130000, group[0].AvgSalary); + Assert.Equal(11300, group[0].AvgSalaryDecimal); + Assert.Equal(1120000, group[0].MinSalary); + Assert.Equal(1140000, group[0].MaxSalary); + } + [Fact] + public void Group_API_Test2() + { + var ids = new[] { "200", "300" }; + var dateOfMonths = new[] { 202111, 202110 }; + var group = _virtualDbContext.Set() + .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth)) + .GroupBy(g => new { UId = g.UserId }) + .Select(g => new + { + + GroupUserId = g.Key.UId, + Count = g.Count(), + TotalSalary = g.Sum(o => o.Salary), + AvgSalary = g.Average(o => o.Salary), + AvgSalaryDecimal = g.Average(o => o.SalaryDecimal), + MinSalary = g.Min(o => o.Salary), + MaxSalary = g.Max(o => o.Salary) + }).OrderByDescending(o => o.TotalSalary).ToList(); + Assert.Equal(2, group.Count); + Assert.Equal(2, group[0].Count); + Assert.Equal("300", group[0].GroupUserId); + Assert.Equal(2690000, group[0].TotalSalary); + Assert.Equal(1345000, group[0].AvgSalary); + Assert.Equal(13450, group[0].AvgSalaryDecimal); + Assert.Equal(1330000, group[0].MinSalary); + Assert.Equal(1360000, group[0].MaxSalary); + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/LogDayLongVirtualRoute.cs b/src/ShardingCore.Test7x/Shardings/LogDayLongVirtualRoute.cs new file mode 100644 index 00000000..6c299aae --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/LogDayLongVirtualRoute.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Helpers; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.VirtualRoutes.Days; + +namespace ShardingCore.Test.Shardings +{ + public class LogDayLongVirtualRoute:AbstractSimpleShardingDayKeyLongVirtualTableRoute + { + //public override bool? EnableRouteParseCompileCache => true; + protected override bool EnableHintRoute => true; + + public override void Configure(EntityMetadataTableBuilder builder) + { + builder.ShardingProperty(o => o.LogTime); + } + + public override bool AutoCreateTableByTime() + { + return true; + } + + public override DateTime GetBeginTime() + { + return new DateTime(2021, 1, 1); + } + + protected override List CalcTailsOnStart() + { + var beginTime = GetBeginTime().Date; + + var tails = new List(); + //提前创建表 + var nowTimeStamp = new DateTime(2021,11,20).Date; + if (beginTime > nowTimeStamp) + throw new ArgumentException("begin time error"); + var currentTimeStamp = beginTime; + while (currentTimeStamp <= nowTimeStamp) + { + var currentTimeStampLong = ShardingCoreHelper.ConvertDateTimeToLong(currentTimeStamp); + var tail = TimeFormatToTail(currentTimeStampLong); + tails.Add(tail); + currentTimeStamp = currentTimeStamp.AddDays(1); + } + return tails; + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/LogDayVirtualTableRoute.cs b/src/ShardingCore.Test7x/Shardings/LogDayVirtualTableRoute.cs new file mode 100644 index 00000000..6e6b6b2c --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/LogDayVirtualTableRoute.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Sharding.PaginationConfigurations; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.Test.Shardings.PaginationConfigs; +using ShardingCore.VirtualRoutes.Days; + +namespace ShardingCore.Test.Shardings +{ + public class LogDayVirtualTableRoute:AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute + { + //public override bool? EnableRouteParseCompileCache => true; + protected override bool EnableHintRoute => true; + + public override DateTime GetBeginTime() + { + return new DateTime(2021, 1, 1); + } + + + public override void Configure(EntityMetadataTableBuilder builder) + { + builder.ShardingProperty(o => o.LogTime); + builder.TableSeparator(string.Empty); + } + + public override IPaginationConfiguration CreatePaginationConfiguration() + { + return new LogDayPaginationConfiguration(); + } + + public override bool AutoCreateTableByTime() + { + return true; + } + + protected override List CalcTailsOnStart() + { + var beginTime = GetBeginTime().Date; + + var tails = new List(); + //提前创建表 + var nowTimeStamp = new DateTime(2021,11,20).Date; + if (beginTime > nowTimeStamp) + throw new ArgumentException("begin time error"); + var currentTimeStamp = beginTime; + while (currentTimeStamp <= nowTimeStamp) + { + var tail = ShardingKeyToTail(currentTimeStamp); + tails.Add(tail); + currentTimeStamp = currentTimeStamp.AddDays(1); + } + return tails; + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/LogMonthLongvirtualRoute.cs b/src/ShardingCore.Test7x/Shardings/LogMonthLongvirtualRoute.cs new file mode 100644 index 00000000..d154ae15 --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/LogMonthLongvirtualRoute.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.Test.Domain.Maps; +using ShardingCore.VirtualRoutes.Months; + +namespace ShardingCore.Test.Shardings +{ + public class LogMonthLongvirtualRoute:AbstractSimpleShardingMonthKeyLongVirtualTableRoute + { + //public override bool? EnableRouteParseCompileCache => true; + protected override bool EnableHintRoute => true; + + public override bool AutoCreateTableByTime() + { + return true; + } + + public override DateTime GetBeginTime() + { + return new DateTime(2021, 1, 1); + } + + public override void Configure(EntityMetadataTableBuilder builder) + { + builder.ShardingProperty(o => o.LogTime); + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/LogWeekDateTimeVirtualTableRoute.cs b/src/ShardingCore.Test7x/Shardings/LogWeekDateTimeVirtualTableRoute.cs new file mode 100644 index 00000000..e0d4b0e0 --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/LogWeekDateTimeVirtualTableRoute.cs @@ -0,0 +1,28 @@ +using System; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.VirtualRoutes.Weeks; + +namespace ShardingCore.Test.Shardings +{ + public class LogWeekDateTimeVirtualTableRoute:AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute + { + //public override bool? EnableRouteParseCompileCache => true; + protected override bool EnableHintRoute => true; + + public override bool AutoCreateTableByTime() + { + return true; + } + + public override DateTime GetBeginTime() + { + return new DateTime(2021, 1, 1); + } + + public override void Configure(EntityMetadataTableBuilder builder) + { + builder.ShardingProperty(o => o.LogTime); + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/LogWeekTimeLongVirtualTableRoute.cs b/src/ShardingCore.Test7x/Shardings/LogWeekTimeLongVirtualTableRoute.cs new file mode 100644 index 00000000..61438f58 --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/LogWeekTimeLongVirtualTableRoute.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.VirtualRoutes.Weeks; + +namespace ShardingCore.Test.Shardings +{ + public class LogWeekTimeLongVirtualTableRoute : AbstractSimpleShardingWeekKeyLongVirtualTableRoute + { + //public override bool? EnableRouteParseCompileCache => true; + protected override bool EnableHintRoute => true; + + public override bool AutoCreateTableByTime() + { + return true; + } + + public override DateTime GetBeginTime() + { + return new DateTime(2021, 1, 1); + } + + public override void Configure(EntityMetadataTableBuilder builder) + { + builder.ShardingProperty(o => o.LogTime); + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/LogYearDateTimeVirtualRoute.cs b/src/ShardingCore.Test7x/Shardings/LogYearDateTimeVirtualRoute.cs new file mode 100644 index 00000000..30fd1e00 --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/LogYearDateTimeVirtualRoute.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.VirtualRoutes.Years; + +namespace ShardingCore.Test.Shardings +{ + public class LogYearDateTimeVirtualRoute:AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute + { + //public override bool? EnableRouteParseCompileCache => true; + protected override bool EnableHintRoute => true; + + public override bool AutoCreateTableByTime() + { + return true; + } + + public override DateTime GetBeginTime() + { + return new DateTime(2020, 1, 1); + } + public override void Configure(EntityMetadataTableBuilder builder) + { + builder.ShardingProperty(o => o.LogTime); + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/LogYearLongVirtualRoute.cs b/src/ShardingCore.Test7x/Shardings/LogYearLongVirtualRoute.cs new file mode 100644 index 00000000..0d02cf32 --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/LogYearLongVirtualRoute.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.VirtualRoutes.Years; + +namespace ShardingCore.Test.Shardings +{ + public class LogYearLongVirtualRoute:AbstractSimpleShardingYearKeyLongVirtualTableRoute + { + //public override bool? EnableRouteParseCompileCache => true; + protected override bool EnableHintRoute => true; + + public override void Configure(EntityMetadataTableBuilder builder) + { + builder.ShardingProperty(o => o.LogTime); + } + + public override bool AutoCreateTableByTime() + { + return true; + } + + public override DateTime GetBeginTime() + { + return new DateTime(2021, 1, 1); + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/MultiShardingOrderVirtualTableRoute.cs b/src/ShardingCore.Test7x/Shardings/MultiShardingOrderVirtualTableRoute.cs new file mode 100644 index 00000000..4daea050 --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/MultiShardingOrderVirtualTableRoute.cs @@ -0,0 +1,79 @@ +using System; +using System.Linq.Expressions; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Core.VirtualRoutes; +using ShardingCore.Helpers; +using ShardingCore.Test.Common; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.VirtualRoutes.Months; + +namespace ShardingCore.Test.Shardings +{ + public class MultiShardingOrderVirtualTableRoute:AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute + { + public override void Configure(EntityMetadataTableBuilder builder) + { + builder.ShardingProperty(o => o.CreateTime); + builder.ShardingExtraProperty(o => o.Id); + } + + public override Func GetExtraRouteFilter(object shardingKey, ShardingOperatorEnum shardingOperator, string shardingPropertyName) + { + switch (shardingPropertyName) + { + case nameof(MultiShardingOrder.Id): return GetIdRouteFilter(shardingKey, shardingOperator); + default: throw new NotImplementedException(shardingPropertyName); + } + } + + private Func GetIdRouteFilter(object shardingKey, + ShardingOperatorEnum shardingOperator) + { + //解析雪花id 需要考虑异常情况,传入的可能不是雪花id那么可以随机查询一张表 + var analyzeIdToDateTime = SnowflakeId.AnalyzeIdToDateTime(Convert.ToInt64(shardingKey)); + //当前时间的tail + var t = TimeFormatToTail(analyzeIdToDateTime); + //因为是按月分表所以获取下个月的时间判断id是否是在灵界点创建的 + var nextMonthFirstDay = ShardingCoreHelper.GetNextMonthFirstDay(DateTime.Now); + if (analyzeIdToDateTime.AddSeconds(10) > nextMonthFirstDay) + { + var nextT = TimeFormatToTail(nextMonthFirstDay); + + if (shardingOperator == ShardingOperatorEnum.Equal) + { + return tail => tail == t||tail== nextT; + } + } + var currentMonthFirstDay = ShardingCoreHelper.GetCurrentMonthFirstDay(DateTime.Now); + if (analyzeIdToDateTime.AddSeconds(-10) < currentMonthFirstDay) + { + //上个月tail + var nextT = TimeFormatToTail(analyzeIdToDateTime.AddSeconds(-10)); + + if (shardingOperator == ShardingOperatorEnum.Equal) + { + return tail => tail == t || tail == nextT; + } + } + else + { + if (shardingOperator == ShardingOperatorEnum.Equal) + { + return tail => tail == t; + } + } + + return tail => true; + } + + public override bool AutoCreateTableByTime() + { + return true; + } + + public override DateTime GetBeginTime() + { + return new DateTime(2021, 9, 1); + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/OrderAreaShardingVirtualDataSourceRoute.cs b/src/ShardingCore.Test7x/Shardings/OrderAreaShardingVirtualDataSourceRoute.cs new file mode 100644 index 00000000..26f28170 --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/OrderAreaShardingVirtualDataSourceRoute.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Core.VirtualRoutes; +using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Shardings +{ + public class OrderAreaShardingVirtualDataSourceRoute:AbstractShardingOperatorVirtualDataSourceRoute + { + //public override bool? EnableRouteParseCompileCache => true; + protected override bool EnableHintRoute =>true; + + private readonly List _dataSources = new List() + { + "A", "B", "C" + }; + //我们设置区域就是数据库 + public override string ShardingKeyToDataSourceName(object shardingKey) + { + return shardingKey?.ToString() ?? string.Empty; + } + + public override List GetAllDataSourceNames() + { + return _dataSources; + } + + public override bool AddDataSourceName(string dataSourceName) + { + if (_dataSources.Any(o => o == dataSourceName)) + return false; + _dataSources.Add(dataSourceName); + return true; + } + + public override void Configure(EntityMetadataDataSourceBuilder builder) + { + builder.ShardingProperty(o => o.Area); + } + + public override Func GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator) + { + + var t = ShardingKeyToDataSourceName(shardingKey); + switch (shardingOperator) + { + case ShardingOperatorEnum.Equal: return tail => tail == t; + default: + { + return tail => true; + } + } + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/OrderCreateTimeVirtualTableRoute.cs b/src/ShardingCore.Test7x/Shardings/OrderCreateTimeVirtualTableRoute.cs new file mode 100644 index 00000000..2ab38dd0 --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/OrderCreateTimeVirtualTableRoute.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Sharding.PaginationConfigurations; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.VirtualRoutes.Months; + +namespace ShardingCore.Test.Shardings +{ + public class OrderCreateTimeVirtualTableRoute:AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute + { + //public override bool? EnableRouteParseCompileCache => true; + public override DateTime GetBeginTime() + { + return new DateTime(2021, 1, 1); + } + + protected override List CalcTailsOnStart() + { + var allTails = base.CalcTailsOnStart(); + allTails.Add("202112"); + return allTails; + } + + public override void Configure(EntityMetadataTableBuilder builder) + { + builder.ShardingProperty(o => o.CreateTime); + } + + public override IPaginationConfiguration CreatePaginationConfiguration() + { + return new OrderCreateTimePaginationConfiguration(); + } + public override bool AutoCreateTableByTime() + { + return true; + } + } + //public class HistoryMinCompare : IComparer + //{ + // private const string History = "History"; + + // public int Compare(string? x, string? y) + // { + // if (!Object.Equals(x, y)) + // { + // if (History.Equals(x)) + // return -1; + // if (History.Equals(y)) + // return 1; + // } + // return Comparer.Default.Compare(x, y); + // } + //} + + public class OrderCreateTimePaginationConfiguration : IPaginationConfiguration + { + public void Configure(PaginationBuilder builder) + { + builder.PaginationSequence(o => o.CreateTime) + .UseQueryMatch(PaginationMatchEnum.Owner | PaginationMatchEnum.Named | PaginationMatchEnum.PrimaryMatch) + .UseAppendIfOrderNone().UseRouteComparer(Comparer.Default); + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/PaginationConfigs/LogDayPaginationConfiguration.cs b/src/ShardingCore.Test7x/Shardings/PaginationConfigs/LogDayPaginationConfiguration.cs new file mode 100644 index 00000000..a7c65dc0 --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/PaginationConfigs/LogDayPaginationConfiguration.cs @@ -0,0 +1,15 @@ +using ShardingCore.Sharding.PaginationConfigurations; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Shardings.PaginationConfigs +{ + public class LogDayPaginationConfiguration: IPaginationConfiguration + { + public void Configure(PaginationBuilder builder) + { + builder.PaginationSequence(o => o.LogTime) + .UseQueryMatch(PaginationMatchEnum.Named | PaginationMatchEnum.Owner | + PaginationMatchEnum.PrimaryMatch).UseAppendIfOrderNone(); + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/SysUserModIntVirtualRoute.cs b/src/ShardingCore.Test7x/Shardings/SysUserModIntVirtualRoute.cs new file mode 100644 index 00000000..8a42588e --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/SysUserModIntVirtualRoute.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.VirtualRoutes.Mods; + +namespace ShardingCore.Test.Shardings +{ + public class SysUserModIntVirtualRoute:AbstractSimpleShardingModKeyIntVirtualTableRoute + { + protected override bool EnableHintRoute => true; + //public override bool? EnableRouteParseCompileCache => true; + + public SysUserModIntVirtualRoute() : base(2, 3) + { + } + + public override void Configure(EntityMetadataTableBuilder builder) + { + builder.ShardingProperty(o => o.Id); + } + } +} diff --git a/src/ShardingCore.Test7x/Shardings/SysUserModVirtualTableRoute.cs b/src/ShardingCore.Test7x/Shardings/SysUserModVirtualTableRoute.cs new file mode 100644 index 00000000..d102f543 --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/SysUserModVirtualTableRoute.cs @@ -0,0 +1,28 @@ +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.VirtualRoutes.Mods; + +namespace ShardingCore.Test.Shardings +{ + /* + * @Author: xjm + * @Description: + * @Date: Thursday, 14 January 2021 15:39:27 + * @Email: 326308290@qq.com + */ + public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute + { + protected override bool EnableHintRoute => true; + //public override bool? EnableRouteParseCompileCache => true; + + public SysUserModVirtualTableRoute() : base(2,3) + { + } + + public override void Configure(EntityMetadataTableBuilder builder) + { + builder.ShardingProperty(o => o.Id); + builder.TableSeparator("_"); + } + } +} \ No newline at end of file diff --git a/src/ShardingCore.Test7x/Shardings/SysUserSalaryVirtualTableRoute.cs b/src/ShardingCore.Test7x/Shardings/SysUserSalaryVirtualTableRoute.cs new file mode 100644 index 00000000..20e42b59 --- /dev/null +++ b/src/ShardingCore.Test7x/Shardings/SysUserSalaryVirtualTableRoute.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using ShardingCore.Core.EntityMetadatas; +using ShardingCore.Core.VirtualRoutes; +using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions; +using ShardingCore.Test.Domain.Entities; + +namespace ShardingCore.Test.Shardings +{ +/* +* @Author: xjm +* @Description: +* @Date: Monday, 01 February 2021 15:54:55 +* @Email: 326308290@qq.com +*/ + public class SysUserSalaryVirtualTableRoute:AbstractShardingOperatorVirtualTableRoute + { + //public override bool? EnableRouteParseCompileCache => true; + protected override bool EnableHintRoute => true; + + public override string ShardingKeyToTail(object shardingKey) + { + var time = Convert.ToInt32(shardingKey); + return TimeFormatToTail(time); + } + + public override List GetTails() + { + var beginTime = new DateTime(2020, 1, 1); + var endTime = new DateTime(2021, 12, 1); + var list = new List(24); + var tempTime = beginTime; + while (tempTime <= endTime) + { + list.Add($"{tempTime:yyyyMM}"); + tempTime = tempTime.AddMonths(1); + } + + return list; + } + + protected string TimeFormatToTail(int time) + { + var dateOfMonth=DateTime.ParseExact($"{time}","yyyyMM",System.Globalization.CultureInfo.InvariantCulture,System.Globalization.DateTimeStyles.AdjustToUniversal); + return $"{dateOfMonth:yyyyMM}"; + } + + public override Func GetRouteToFilter(int shardingKey, ShardingOperatorEnum shardingOperator) + { + var t = TimeFormatToTail(shardingKey); + switch (shardingOperator) + { + case ShardingOperatorEnum.GreaterThan: + case ShardingOperatorEnum.GreaterThanOrEqual: + return tail => String.Compare(tail, t, StringComparison.Ordinal) >= 0; + case ShardingOperatorEnum.LessThan: + 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 void Configure(EntityMetadataTableBuilder builder) + { + builder.ShardingProperty(o => o.DateOfMonth); + } + } +} \ No newline at end of file diff --git a/src/ShardingCore.Test7x/Startup.cs b/src/ShardingCore.Test7x/Startup.cs new file mode 100644 index 00000000..b077e64e --- /dev/null +++ b/src/ShardingCore.Test7x/Startup.cs @@ -0,0 +1,383 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using ShardingCore.Bootstrappers; +using ShardingCore.Core; +using ShardingCore.Helpers; +using ShardingCore.Sharding.ReadWriteConfigurations; +using ShardingCore.TableExists; +using ShardingCore.TableExists.Abstractions; +using ShardingCore.Test.Domain.Entities; +using ShardingCore.Test.Shardings; + +namespace ShardingCore.Test +{ + /* + * @Author: xjm + * @Description: + * @Date: Friday, 15 January 2021 15:37:46 + * @Email: 326308290@qq.com + */ + public class Startup + { + public static readonly ILoggerFactory efLogger = LoggerFactory.Create(builder => + { + builder.AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information).AddConsole(); + }); + + // 支持的形式: + // ConfigureServices(IServiceCollection services) + // ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext) + // ConfigureServices(HostBuilderContext hostBuilderContext, IServiceCollection services) + public void ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext) + { + services.AddShardingDbContext() + .UseRouteConfig(op => + { + op.AddShardingDataSourceRoute(); + op.AddShardingTableRoute(); + op.AddShardingTableRoute(); + op.AddShardingTableRoute(); + op.AddShardingTableRoute(); + op.AddShardingTableRoute(); + op.AddShardingTableRoute(); + op.AddShardingTableRoute(); + op.AddShardingTableRoute(); + op.AddShardingTableRoute(); + op.AddShardingTableRoute(); + op.AddShardingTableRoute(); + op.AddShardingTableRoute(); + + }) + .UseConfig(op => + { + op.AutoUseWriteConnectionStringAfterWriteDb = true; + op.CacheModelLockConcurrencyLevel = Environment.ProcessorCount; + //op.UseEntityFrameworkCoreProxies = true; + //当无法获取路由时会返回默认值而不是报错 + op.ThrowIfQueryRouteNotMatch = false; + //忽略建表错误compensate table和table creator + op.IgnoreCreateTableError = true; + //迁移时使用的并行线程数(分库有效)defaultShardingDbContext.Database.Migrate() + op.MigrationParallelCount = Environment.ProcessorCount; + //补偿表创建并行线程数 调用UseAutoTryCompensateTable有效 + op.CompensateTableParallelCount = Environment.ProcessorCount; + //最大连接数限制 + op.MaxQueryConnectionsLimit = Environment.ProcessorCount; + //链接模式系统默认 + op.ConnectionMode = ConnectionModeEnum.SYSTEM_AUTO; + //如何通过字符串查询创建DbContext + op.UseShardingQuery((conStr, builder) => + { + builder.UseSqlServer(conStr).UseLoggerFactory(efLogger); + }); + //如何通过事务创建DbContext + op.UseShardingTransaction((connection, builder) => + { + builder.UseSqlServer(connection).UseLoggerFactory(efLogger); + }); + //添加默认数据源 + op.AddDefaultDataSource("A", + "Data Source=localhost;Initial Catalog=ShardingCoreDBA;Integrated Security=True;TrustServerCertificate=True;"); + //添加额外数据源 + op.AddExtraDataSource(sp => + { + return new Dictionary() + { + { "B", "Data Source=localhost;Initial Catalog=ShardingCoreDBB;Integrated Security=True;TrustServerCertificate=True;" }, + { "C", "Data Source=localhost;Initial Catalog=ShardingCoreDBC;Integrated Security=True;TrustServerCertificate=True;" }, + }; + }); + //添加读写分离 + op.AddReadWriteSeparation(sp => + { + return new Dictionary>() + { + { + "A", new HashSet() + { + "Data Source=localhost;Initial Catalog=ShardingCoreDBB;Integrated Security=True;TrustServerCertificate=True;" + } + } + }; + }, ReadStrategyEnum.Loop, defaultEnable: false, readConnStringGetStrategy: ReadConnStringGetStrategyEnum.LatestEveryTime); + }) + .AddShardingCore(); + } + + // 可以添加要用到的方法参数,会自动从注册的服务中获取服务实例,类似于 asp.net core 里 Configure 方法 + public void Configure(IServiceProvider serviceProvider) + { + //启动ShardingCore创建表任务 + //启动进行表补偿 + serviceProvider.UseAutoTryCompensateTable(); + // 有一些测试数据要初始化可以放在这里 + InitData(serviceProvider).GetAwaiter().GetResult(); + } + + /// + /// 添加种子数据 + /// + /// + /// + private async Task InitData(IServiceProvider serviceProvider) + { + using (var scope = serviceProvider.CreateScope()) + { + var virtualDbContext = scope.ServiceProvider.GetService(); + if (!await virtualDbContext.Set().AnyAsync()) + { + var ids = Enumerable.Range(1, 1000); + var userMods = new List(); + var userModInts = new List(); + var userSalaries = new List(); + var beginTime = new DateTime(2020, 1, 1); + var endTime = new DateTime(2021, 12, 1); + foreach (var id in ids) + { + userMods.Add(new SysUserMod() + { + Id = id.ToString(), + Age = id, + Name = $"name_{id}", + AgeGroup = Math.Abs(id % 10) + }); + userModInts.Add(new SysUserModInt() + { + Id = id, + Age = id, + Name = $"name_{id}", + AgeGroup = Math.Abs(id % 10) + }); + var tempTime = beginTime; + var i = 0; + while (tempTime <= endTime) + { + var dateOfMonth = $@"{tempTime:yyyyMM}"; + userSalaries.Add(new SysUserSalary() + { + Id = $@"{id}{dateOfMonth}", + UserId = id.ToString(), + DateOfMonth = int.Parse(dateOfMonth), + Salary = 700000 + id * 100 * i, + SalaryLong = 700000 + id * 100 * i, + SalaryDecimal = (700000 + id * 100 * i) / 100m, + SalaryDouble = (700000 + id * 100 * i) / 100d, + SalaryFloat = (700000 + id * 100 * i) / 100f + }); + tempTime = tempTime.AddMonths(1); + i++; + } + } + + var areas = new List(){"A","B","C"}; + List orders = new List(360); + var begin = new DateTime(2021, 1, 1); + for (int i = 0; i < 320; i++) + { + orders.Add(new Order() + { + Id = Guid.NewGuid(), + Area = areas[i%3], + CreateTime = begin, + Money = i + }); + begin = begin.AddDays(1); + } + + List logDays = new List(3600); + List logDayLongs = new List(3600); + + var levels = new List(){"info","warning","error"}; + var begin1 = new DateTime(2021, 1, 1); + for (int i = 0; i < 300; i++) + { + var ltime = begin1; + for (int j = 0; j < 10; j++) + { + logDays.Add(new LogDay() + { + Id = Guid.NewGuid(), + LogLevel = levels[j%3], + LogBody = $"{i}_{j}", + LogTime = ltime.AddHours(1) + }); + logDayLongs.Add(new LogDayLong() + { + Id = Guid.NewGuid(), + LogLevel = levels[j%3], + LogBody = $"{i}_{j}", + LogTime = ShardingCoreHelper.ConvertDateTimeToLong(ltime.AddHours(1)) + }); + ltime = ltime.AddHours(1); + } + begin1 = begin1.AddDays(1); + } + + List logWeeks = new List(300); + var begin2 = new DateTime(2021,1,1); + for (int i = 0; i < 300; i++) + { + logWeeks.Add(new LogWeekDateTime() + { + Id = Guid.NewGuid().ToString("n"), + Body = $"body_{i}", + LogTime = begin2 + }); + begin2 = begin2.AddDays(1); + } + List logWeekLongs = new List(300); + var begin3 = new DateTime(2021,1,1); + for (int i = 0; i < 300; i++) + { + logWeekLongs.Add(new LogWeekTimeLong() + { + Id = Guid.NewGuid().ToString("n"), + Body = $"body_{i}", + LogTime = ShardingCoreHelper.ConvertDateTimeToLong(begin3) + }); + begin3 = begin3.AddDays(1); + } + List logYears = new List(600); + var begin4 = new DateTime(2020,1,1); + for (int i = 0; i < 600; i++) + { + logYears.Add(new LogYearDateTime() + { + Id = Guid.NewGuid(), + LogBody = $"body_{i}", + LogTime = begin4 + }); + begin4 = begin4.AddDays(1); + } + + + List logMonthLongs = new List(300); + var begin5 = new DateTime(2021, 1, 1); + for (int i = 0; i < 300; i++) + { + logMonthLongs.Add(new LogMonthLong() + { + Id = Guid.NewGuid().ToString("n"), + Body = $"body_{i}", + LogTime = ShardingCoreHelper.ConvertDateTimeToLong(begin5) + }); + begin5 = begin5.AddDays(1); + } + + List logYearkLongs = new List(300); + var begin6 = new DateTime(2021, 1, 1); + for (int i = 0; i < 300; i++) + { + logYearkLongs.Add(new LogYearLong() + { + Id = Guid.NewGuid().ToString("n"), + LogBody = $"body_{i}", + LogTime = ShardingCoreHelper.ConvertDateTimeToLong(begin6) + }); + begin6 = begin6.AddDays(1); + } + var multiShardingOrders = new List(9); + #region 添加多字段分表 + + { + var now = new DateTime(2021, 10, 1, 13, 13, 11); + multiShardingOrders.Add(new MultiShardingOrder() + { + Id = 231765457240207360, + Name = $"{now:yyyy/MM/dd HH:mm:ss}", + CreateTime = now + }); + } + { + var now = new DateTime(2021, 10, 2, 11, 3, 11); + multiShardingOrders.Add(new MultiShardingOrder() + { + Id = 232095129534607360, + Name = $"{now:yyyy/MM/dd HH:mm:ss}", + CreateTime = now + }); + } + { + var now = new DateTime(2021, 10, 3, 7, 7, 7); + multiShardingOrders.Add(new MultiShardingOrder() + { + Id = 232398109278351360, + Name = $"{now:yyyy/MM/dd HH:mm:ss}", + CreateTime = now + }); + } + { + var now = new DateTime(2021, 11, 6, 13, 13, 11); + multiShardingOrders.Add(new MultiShardingOrder() + { + Id = 244811420401807360, + Name = $"{now:yyyy/MM/dd HH:mm:ss}", + CreateTime = now + }); + } + { + var now = new DateTime(2021, 11, 21, 19, 43, 0); + multiShardingOrders.Add(new MultiShardingOrder() + { + Id = 250345338962063360, + Name = $"{now:yyyy/MM/dd HH:mm:ss}", + CreateTime = now + }); + } + { + var now = new DateTime(2021, 12, 5, 5, 5, 11); + multiShardingOrders.Add(new MultiShardingOrder() + { + Id = 255197859283087360, + Name = $"{now:yyyy/MM/dd HH:mm:ss}", + CreateTime = now + }); + } + { + var now = new DateTime(2021, 12, 9, 19, 13, 11); + multiShardingOrders.Add(new MultiShardingOrder() + { + Id = 256860816933007360, + Name = $"{now:yyyy/MM/dd HH:mm:ss}", + CreateTime = now + }); + } + { + var now = new DateTime(2021, 12, 19, 13, 13, 11); + multiShardingOrders.Add(new MultiShardingOrder() + { + Id = 260394098622607360, + Name = $"{now:yyyy/MM/dd HH:mm:ss}", + CreateTime = now + }); + } + #endregion + using (var tran = virtualDbContext.Database.BeginTransaction()) + { + await virtualDbContext.AddRangeAsync(userMods); + await virtualDbContext.AddRangeAsync(userModInts); + await virtualDbContext.AddRangeAsync(userSalaries); + await virtualDbContext.AddRangeAsync(orders); + await virtualDbContext.AddRangeAsync(logDays); + await virtualDbContext.AddRangeAsync(logDayLongs); + await virtualDbContext.AddRangeAsync(logWeeks); + await virtualDbContext.AddRangeAsync(logWeekLongs); + await virtualDbContext.AddRangeAsync(logYears); + await virtualDbContext.AddRangeAsync(logMonthLongs); + await virtualDbContext.AddRangeAsync(logYearkLongs); + await virtualDbContext.AddRangeAsync(multiShardingOrders); + + await virtualDbContext.SaveChangesAsync(); + tran.Commit(); + } + } + } + } + } +} \ No newline at end of file diff --git a/test/ShardingCore.CommonTest/ShardingCore.CommonTest.csproj b/test/ShardingCore.CommonTest/ShardingCore.CommonTest.csproj index 1525beea..5ed33923 100644 --- a/test/ShardingCore.CommonTest/ShardingCore.CommonTest.csproj +++ b/test/ShardingCore.CommonTest/ShardingCore.CommonTest.csproj @@ -1,7 +1,7 @@ - + - net6.0 + net8.0 enable enable diff --git a/test/ShardingCore.Test/ShardingCore.Test.csproj b/test/ShardingCore.Test/ShardingCore.Test.csproj index 72ffe503..57a1b182 100644 --- a/test/ShardingCore.Test/ShardingCore.Test.csproj +++ b/test/ShardingCore.Test/ShardingCore.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 TRACE;DEBUG;EFCORE6Test; ShardingCore.Test latest @@ -9,8 +9,8 @@ - - + + diff --git a/test/ShardingCore.Test/Startup.cs b/test/ShardingCore.Test/Startup.cs index b077e64e..6f018ecb 100644 --- a/test/ShardingCore.Test/Startup.cs +++ b/test/ShardingCore.Test/Startup.cs @@ -74,12 +74,12 @@ namespace ShardingCore.Test //如何通过字符串查询创建DbContext op.UseShardingQuery((conStr, builder) => { - builder.UseSqlServer(conStr).UseLoggerFactory(efLogger); + builder.UseSqlServer(conStr, o => o.UseCompatibilityLevel(120)).UseLoggerFactory(efLogger); }); //如何通过事务创建DbContext op.UseShardingTransaction((connection, builder) => { - builder.UseSqlServer(connection).UseLoggerFactory(efLogger); + builder.UseSqlServer(connection, o => o.UseCompatibilityLevel(120)).UseLoggerFactory(efLogger); }); //添加默认数据源 op.AddDefaultDataSource("A",