仅初步集成了efcore6

This commit is contained in:
xuejiaming 2021-11-09 10:51:18 +08:00
parent 57d11dff5a
commit 3769fe0d6c
27 changed files with 1052 additions and 44 deletions

View File

@ -47,9 +47,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore.5x", "src5x\Sh
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Migrations", "samples\Sample.Migrations\Sample.Migrations.csproj", "{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.SqlServerShardingTable", "samples\Sample.SqlServerShardingTable\Sample.SqlServerShardingTable.csproj", "{88FA5615-1BAA-4021-87EF-9D4A60257FE4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.SqlServerShardingTable", "samples\Sample.SqlServerShardingTable\Sample.SqlServerShardingTable.csproj", "{88FA5615-1BAA-4021-87EF-9D4A60257FE4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.SqlServerShardingAll", "samples\Sample.SqlServerShardingAll\Sample.SqlServerShardingAll.csproj", "{FD2C6D03-8D6D-4C1C-B534-4C785A4B1B06}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.SqlServerShardingAll", "samples\Sample.SqlServerShardingAll\Sample.SqlServerShardingAll.csproj", "{FD2C6D03-8D6D-4C1C-B534-4C785A4B1B06}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShardingCore.Test6x", "test\ShardingCore.Test6x\ShardingCore.Test6x.csproj", "{71D85D50-7F2B-4FEF-BC6F-A80DBDDAC7E8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -129,6 +131,10 @@ Global
{FD2C6D03-8D6D-4C1C-B534-4C785A4B1B06}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD2C6D03-8D6D-4C1C-B534-4C785A4B1B06}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD2C6D03-8D6D-4C1C-B534-4C785A4B1B06}.Release|Any CPU.Build.0 = Release|Any CPU
{71D85D50-7F2B-4FEF-BC6F-A80DBDDAC7E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{71D85D50-7F2B-4FEF-BC6F-A80DBDDAC7E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{71D85D50-7F2B-4FEF-BC6F-A80DBDDAC7E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{71D85D50-7F2B-4FEF-BC6F-A80DBDDAC7E8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -152,6 +158,7 @@ Global
{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
{88FA5615-1BAA-4021-87EF-9D4A60257FE4} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
{FD2C6D03-8D6D-4C1C-B534-4C785A4B1B06} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
{71D85D50-7F2B-4FEF-BC6F-A80DBDDAC7E8} = {CC2C88C0-65F2-445D-BE78-973B840FE281}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8C07A667-E8B4-43C7-8053-721584BAD291}

View File

@ -3,6 +3,7 @@
set EFCORE2=2.3.1.30
set EFCORE3=3.3.1.30
set EFCORE5=5.3.1.30
set EFCORE6=5.3.1.30
::删除所有bin与obj下的文件
@echo off

View File

@ -194,6 +194,7 @@ namespace ShardingCore.Bootstrapers
if (context is IShardingDbContext shardingDbContext)
{
var dbContext = shardingDbContext.GetDbContext(dataSourceName, false, _routeTailFactory.Create(string.Empty));
var modelCacheSyncObject = dbContext.GetModelCacheSyncObject();
lock (modelCacheSyncObject)

View File

@ -13,8 +13,43 @@ namespace ShardingCore.EFCores.OptionsExtensions
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
#if !EFCORE2
public class ShardingWrapOptionsExtension: IDbContextOptionsExtension
#if EFCORE6
public class ShardingWrapOptionsExtension : IDbContextOptionsExtension
{
public void ApplyServices(IServiceCollection services)
{
}
public void Validate(IDbContextOptions options)
{
}
public DbContextOptionsExtensionInfo Info => new ShardingWrapDbContextOptionsExtensionInfo(this);
private class ShardingWrapDbContextOptionsExtensionInfo : DbContextOptionsExtensionInfo
{
public ShardingWrapDbContextOptionsExtensionInfo(IDbContextOptionsExtension extension) : base(extension)
{
}
public override int GetServiceProviderHashCode() => 0;
public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo other) => true;
public override void PopulateDebugInfo(IDictionary<string, string> debugInfo)
{
}
public override bool IsDatabaseProvider => false;
public override string LogFragment => "ShardingWrapOptionsExtension";
}
}
#endif
#if EFCORE3 || EFCORE5
public class ShardingWrapOptionsExtension: IDbContextOptionsExtension
{
public void ApplyServices(IServiceCollection services)
{
@ -39,6 +74,7 @@ namespace ShardingCore.EFCores.OptionsExtensions
public override string LogFragment => "ShardingWrapOptionsExtension";
}
}
#endif
#if EFCORE2

View File

@ -23,7 +23,14 @@ namespace ShardingCore.EFCores
{
private readonly ISupportShardingTransaction _supportShardingTransaction;
private bool supportShardingTransaction => _supportShardingTransaction != null;
#if !EFCORE2
#if EFCORE6
public ShardingRelationalTransaction(ISupportShardingTransaction supportShardingTransaction, IRelationalConnection connection, DbTransaction transaction, Guid transactionId, IDiagnosticsLogger<DbLoggerCategory.Database.Transaction> logger, bool transactionOwned, ISqlGenerationHelper sqlGenerationHelper) : base(connection, transaction, transactionId, logger, transactionOwned, sqlGenerationHelper)
{
_supportShardingTransaction = supportShardingTransaction;
}
#endif
#if EFCORE3 || EFCORE5
public ShardingRelationalTransaction(ISupportShardingTransaction supportShardingTransaction, IRelationalConnection connection, DbTransaction transaction, Guid transactionId, IDiagnosticsLogger<DbLoggerCategory.Database.Transaction> logger, bool transactionOwned) : base(connection, transaction, transactionId, logger, transactionOwned)
{
_supportShardingTransaction = supportShardingTransaction;

View File

@ -12,7 +12,7 @@ namespace ShardingCore.EFCores
* @Date: Saturday, 14 August 2021 10:17:43
* @Email: 326308290@qq.com
*/
#if EFCORE5
#if EFCORE5 || EFCORE6
public class ShardingDbSetSource : IDbSetSource
{

View File

@ -30,14 +30,15 @@ namespace ShardingCore.EFCores
where TEntity : class
{
private readonly IShardingDbContext _context;
#if EFCORE5
#if EFCORE5 || EFCORE6
public ShardingInternalDbSet(DbContext context, string entityTypeName) : base(context, entityTypeName)
{
_context = (IShardingDbContext)context;
}
#endif
#if !EFCORE5
#if EFCORE2 || EFCORE3
public ShardingInternalDbSet(DbContext context) : base(context)
{
@ -432,7 +433,6 @@ namespace ShardingCore.EFCores
return VirtualDataSource.DefaultDataSourceName;
return VirtualDataSource.GetDataSourceName<TEntity>(shardingKeyValue);
}
}
}

View File

@ -13,18 +13,24 @@ namespace ShardingCore.EFCores
* @Date: Wednesday, 16 December 2020 16:13:05
* @Email: 326308290@qq.com
*/
public class ShardingModelCacheKeyFactory : IModelCacheKeyFactory
{
public object Create(DbContext context)
{
return Create(context, false);
}
public object Create(DbContext context, bool designTime)
{
if (context is IShardingTableDbContext shardingTableDbContext && shardingTableDbContext.RouteTail != null && !string.IsNullOrWhiteSpace(shardingTableDbContext.RouteTail.GetRouteTailIdentity()))
{
return $"{context.GetType()}_{shardingTableDbContext.RouteTail.GetRouteTailIdentity()}";
return $"{context.GetType()}_{shardingTableDbContext.RouteTail.GetRouteTailIdentity()}_{designTime}";
}
else
{
return context.GetType();
return (context.GetType(),designTime);
}
}
}

View File

@ -18,7 +18,24 @@ namespace ShardingCore.EFCores
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
#if !EFCORE2
#if EFCORE6
public class ShardingRelationalTransactionFactory<TShardingDbContext> : RelationalTransactionFactory where TShardingDbContext : DbContext, IShardingDbContext
{
private readonly RelationalTransactionFactoryDependencies _dependencies;
public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies)
{
_dependencies = dependencies;
}
public override RelationalTransaction Create(IRelationalConnection connection, DbTransaction transaction, Guid transactionId,
IDiagnosticsLogger<DbLoggerCategory.Database.Transaction> logger, bool transactionOwned)
{
var supportShardingTransaction = connection.Context as ISupportShardingTransaction;
return new ShardingRelationalTransaction(supportShardingTransaction, connection, transaction, transactionId, logger, transactionOwned, this.Dependencies.SqlGenerationHelper);
}
}
#endif
#if EFCORE3 || EFCORE5
public class ShardingRelationalTransactionFactory<TShardingDbContext> : RelationalTransactionFactory where TShardingDbContext : DbContext, IShardingDbContext
{

View File

@ -26,10 +26,26 @@ namespace ShardingCore.Extensions
/// <param name="dbContext"></param>
public static void RemoveDbContextRelationModelThatIsShardingTable(this DbContext dbContext)
{
#if EFCORE6
var contextModel = dbContext.Model as RuntimeModel;
#endif
#if EFCORE2 || EFCORE3 || EFCORE5
var contextModel = dbContext.Model as Model;
#endif
var entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(dbContext.GetType()));
#if EFCORE5
#if EFCORE6
var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel;
var valueTuples =
contextModelRelationalModel.Tables.Where(o =>o.Value.EntityTypeMappings.Any(m => entityMetadataManager.IsShardingTable(m.EntityType.ClrType))).Select(o => o.Key).ToList();
for (int i = 0; i < valueTuples.Count; i++)
{
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
}
#endif
#if EFCORE5
var contextModelRelationalModel = contextModel.RelationalModel as RelationalModel;
var valueTuples =
contextModelRelationalModel.Tables.Where(o => o.Value.EntityTypeMappings.Any(m => entityMetadataManager.IsShardingTable(m.EntityType.ClrType))).Select(o => o.Key).ToList();
@ -38,7 +54,7 @@ namespace ShardingCore.Extensions
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
}
#endif
#if !EFCORE5
#if EFCORE2 ||EFCORE3
var entityTypes =
contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>;
var list = entityTypes.Where(o=>entityMetadataManager.IsShardingTable(o.Value.ClrType)).Select(o=>o.Key).ToList();
@ -57,7 +73,25 @@ namespace ShardingCore.Extensions
public static void RemoveDbContextRelationModelSaveOnlyThatIsNamedType(this DbContext dbContext,
Type shardingType)
{
#if EFCORE6
var contextModel = dbContext.Model as RuntimeModel;
#endif
#if EFCORE2 ||EFCORE3 ||EFCORE5
var contextModel = dbContext.Model as Model;
#endif
#if EFCORE6
var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel;
var valueTuples =
contextModelRelationalModel.Tables
.Where(o => o.Value.EntityTypeMappings.All(m => m.EntityType.ClrType != shardingType))
.Select(o => o.Key).ToList();
for (int i = 0; i < valueTuples.Count; i++)
{
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
}
#endif
#if EFCORE5
var contextModelRelationalModel = contextModel.RelationalModel as RelationalModel;
@ -69,7 +103,7 @@ namespace ShardingCore.Extensions
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
}
#endif
#if !EFCORE5
#if EFCORE2 || EFCORE3
var entityTypes =
contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>;
var list = entityTypes.Where(o=>o.Value.ClrType!=shardingType).Select(o=>o.Key).ToList();
@ -93,6 +127,16 @@ namespace ShardingCore.Extensions
public static void RemoveModelCache(this DbContext dbContext)
{
var serviceScope = typeof(DbContext).GetTypeFieldValue(dbContext, "_serviceScope") as IServiceScope;
#if EFCORE6
var dependencies = serviceScope.ServiceProvider.GetService<ModelCreationDependencies>();
var dependenciesModelSource = dependencies.ModelSource as ModelSource;
var modelSourceDependencies =
dependenciesModelSource.GetPropertyValue("Dependencies") as ModelSourceDependencies;
IMemoryCache memoryCache = modelSourceDependencies.MemoryCache;
object key1 = modelSourceDependencies.ModelCacheKeyFactory.Create(dbContext);
memoryCache.Remove(key1);
#endif
#if EFCORE5
var dependencies = serviceScope.ServiceProvider.GetService<IModelCreationDependencies>();
var dependenciesModelSource = dependencies.ModelSource as ModelSource;
@ -136,16 +180,22 @@ namespace ShardingCore.Extensions
/// <returns></returns>
public static object GetModelCacheSyncObject(this DbContext dbContext)
{
var serviceScope = typeof(DbContext).GetTypeFieldValue(dbContext, "_serviceScope") as IServiceScope;
#if EFCORE5
var dependencies = serviceScope.ServiceProvider.GetService<IModelCreationDependencies>();
#if EFCORE6
var dependencies = dbContext.GetService<ModelCreationDependencies>();
var dependenciesModelSource = dependencies.ModelSource as ModelSource;
var syncObject = dependenciesModelSource.GetFieldValue("_syncObject");
return syncObject;
#endif
#if EFCORE5
var dependencies = dbContext.GetService<IModelCreationDependencies>();
var dependenciesModelSource = dependencies.ModelSource as ModelSource;
var syncObject = dependenciesModelSource.GetFieldValue("_syncObject");
return syncObject;
#endif
#if EFCORE3
var modelSource = serviceScope.ServiceProvider.GetService<IModelSource>();
var modelSource = dbContext.GetService<IModelSource>();
var modelSourceImpl = modelSource as ModelSource;
var syncObject = modelSourceImpl.GetFieldValue("_syncObject");

View File

@ -185,7 +185,7 @@ namespace ShardingCore.Sharding.Enumerators.AggregateExtensions
// We're going to find one that matches the type of our property.
MethodInfo maxMethod = typeof(Queryable).GetMethods().First(
m => m.Name == nameof(Queryable.Max)
&& m.GetParameters().Length==2
&& m.GetParameters().Length==2 && typeof(Expression).IsAssignableFrom(m.GetParameters()[1].ParameterType)
&& m.IsGenericMethod);
// Now that we have the correct method, we need to know how to call the method.
@ -232,7 +232,7 @@ namespace ShardingCore.Sharding.Enumerators.AggregateExtensions
// We're going to find one that matches the type of our property.
MethodInfo minMethod = typeof(Queryable).GetMethods().First(
m => m.Name == nameof(Queryable.Min)
&& m.GetParameters().Length==2
&& m.GetParameters().Length==2 &&typeof(Expression).IsAssignableFrom(m.GetParameters()[1].ParameterType)
&& m.IsGenericMethod);
// Now that we have the correct method, we need to know how to call the method.

View File

@ -9,13 +9,13 @@ using ShardingCore.Extensions;
namespace ShardingCore.Core.Internal.Visitors
{
/*
* @Author: xjm
* @Description:
* @Date: Wednesday, 13 January 2021 16:32:27
* @Email: 326308290@qq.com
*/
#if !EFCORE5
/*
* @Author: xjm
* @Description:
* @Date: Wednesday, 13 January 2021 16:32:27
* @Email: 326308290@qq.com
*/
#if EFCORE2 || EFCORE3
internal class DbContextReplaceQueryableVisitor : ExpressionVisitor
{
private readonly DbContext _dbContext;
@ -43,7 +43,7 @@ namespace ShardingCore.Core.Internal.Visitors
}
#endif
#if EFCORE5
#if EFCORE5 || EFCORE6
internal class DbContextReplaceQueryableVisitor : ExpressionVisitor
{

View File

@ -13,7 +13,7 @@ namespace ShardingCore.Core.Internal.Visitors.Querys
* @Date: Saturday, 20 February 2021 11:14:35
* @Email: 326308290@qq.com
*/
#if !EFCORE5
#if EFCORE2|| EFCORE3
/// <summary>
/// 获取分表类型
/// </summary>
@ -38,7 +38,7 @@ namespace ShardingCore.Core.Internal.Visitors.Querys
}
#endif
#if EFCORE5
#if EFCORE5 || EFCORE6
/// <summary>
/// 获取分表类型
/// </summary>

View File

@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Version>$(EFCORE5)</Version>
<TargetFramework>net6.0</TargetFramework>
<Version>$(EFCORE6)</Version>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<DefineConstants>TRACE;DEBUG;EFCORE5;</DefineConstants>
<DefineConstants>TRACE;DEBUG;EFCORE6;</DefineConstants>
<LangVersion>8.0</LangVersion>
<RepositoryUrl>https://github.com/xuejmnet/sharding-core</RepositoryUrl>
</PropertyGroup>
@ -13,7 +13,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.0" />
</ItemGroup>
</Project>

View File

@ -1,11 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RootNamespace>ShardingCore</RootNamespace>
<AssemblyName>ShardingCore</AssemblyName>
<Description>easy sharding for efcore 2.x 3.x 5.x 6.x lib.</Description>
<RepositoryUrl>https://github.com/xuejmnet/sharding-core</RepositoryUrl>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Version>$(EFCORE5)</Version>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<DefineConstants>TRACE;DEBUG;EFCORE5;</DefineConstants>
<LangVersion>8.0</LangVersion>
<AssemblyName>ShardingCore</AssemblyName>
<RootNamespace>ShardingCore</RootNamespace>
<RepositoryUrl>https://github.com/xuejmnet/sharding-core</RepositoryUrl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<DocumentationFile>bin\Release\ShardingCore.5x.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\src\ShardingCore\**\*.cs" />
<Compile Remove="..\..\src\ShardingCore\obj\**" />
<Compile Remove="..\..\src\ShardingCore\bin\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.12" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.12" />
</ItemGroup>
</Project>

View File

@ -27,7 +27,7 @@
<Content Include="Configs\MacDbConfig.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\ShardingCore\ShardingCore.csproj" />
<ProjectReference Include="..\..\src5x\ShardingCore.5x\ShardingCore.5x.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,9 @@
{
"SqlServer": {
"ConnectionString": "Data Source=localhost;Initial Catalog=ShardingCoreDB;Integrated Security=True;"
},
"MySql": {
"ConnectionString": "server=127.0.0.1;port=3306;user=root;password=root;database=ShardingCoreDB;sslMode=None;"
}
}

View File

@ -0,0 +1,26 @@
namespace ShardingCore.Test6x.Domain.Entities
{
/*
* @Author: xjm
* @Description:
* @Date: Thursday, 14 January 2021 15:36:43
* @Email: 326308290@qq.com
*/
public class SysUserMod
{
/// <summary>
/// 用户Id用于分表
/// </summary>
public string Id { get; set; }
/// <summary>
/// 用户名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 用户姓名
/// </summary>
public int Age { get; set; }
public int AgeGroup { get; set; }
}
}

View File

@ -0,0 +1,41 @@
using ShardingCore.Core;
namespace ShardingCore.Test6x.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; }
/// <summary>
/// 每月的金额
/// </summary>
public int DateOfMonth { get; set; }
/// <summary>
/// 工资
/// </summary>
public int Salary { get; set; }
/// <summary>
/// 工资
/// </summary>
public long SalaryLong { get; set; }
/// <summary>
/// 工资
/// </summary>
public decimal SalaryDecimal { get; set; }
/// <summary>
/// 工资
/// </summary>
public double SalaryDouble { get; set; }
/// <summary>
/// 工资
/// </summary>
public float SalaryFloat { get; set; }
}
}

View File

@ -0,0 +1,23 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using ShardingCore.Test6x.Domain.Entities;
namespace ShardingCore.Test6x.Domain.Maps
{
/*
* @Author: xjm
* @Description:
* @Date: Thursday, 14 January 2021 15:37:33
* @Email: 326308290@qq.com
*/
public class SysUserModMap:IEntityTypeConfiguration<SysUserMod>
{
public void Configure(EntityTypeBuilder<SysUserMod> 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));
}
}
}

View File

@ -0,0 +1,23 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using ShardingCore.Test6x.Domain.Entities;
namespace ShardingCore.Test6x.Domain.Maps
{
/*
* @Author: xjm
* @Description:
* @Date: Monday, 01 February 2021 15:42:35
* @Email: 326308290@qq.com
*/
public class SysUserSalaryMap:IEntityTypeConfiguration<SysUserSalary>
{
public void Configure(EntityTypeBuilder<SysUserSalary> 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));
}
}
}

View File

@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<None Remove="Configs\DbConfig.json" />
<None Remove="Configs\MacDbConfig.json" />
</ItemGroup>
<ItemGroup>
<Content Include="Configs\DbConfig.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="Xunit.DependencyInjection" Version="8.1.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\ShardingCore\ShardingCore.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,31 @@
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Sharding;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Test6x.Domain.Maps;
namespace ShardingCore.Test6x
{
/*
* @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<ShardingDefaultDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfiguration(new SysUserModMap());
modelBuilder.ApplyConfiguration(new SysUserSalaryMap());
}
public IRouteTail RouteTail { get; set; }
}
}

View File

@ -0,0 +1,425 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
using ShardingCore.Test6x.Domain.Entities;
using Xunit;
namespace ShardingCore.Test6x
{
/*
* @Author: xjm
* @Description:
* @Date: Friday, 15 January 2021 17:22:10
* @Email: 326308290@qq.com
*/
public class ShardingTest
{
private readonly ShardingDefaultDbContext _virtualDbContext;
private readonly IShardingRouteManager _shardingRouteManager;
public ShardingTest(ShardingDefaultDbContext virtualDbContext,IShardingRouteManager shardingRouteManager)
{
_virtualDbContext = virtualDbContext;
_shardingRouteManager = shardingRouteManager;
}
//[Fact]
//public async Task Route_TEST()
//{
// var queryable1 = _virtualDbContext.Set<SysUserMod>().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<SysUserMod>().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.MustTable.TryAdd(typeof(SysUserMod), new HashSet<string>() { "00" });
var mod00s = await _virtualDbContext.Set<SysUserMod>().ToListAsync();
Assert.Equal(333, mod00s.Count);
}
var mods = await _virtualDbContext.Set<SysUserMod>().ToListAsync();
Assert.Equal(1000, mods.Count);
var modOrders1 = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Age).ToListAsync();
int ascAge = 1;
foreach (var sysUserMod in modOrders1)
{
Assert.Equal(ascAge, sysUserMod.Age);
ascAge++;
}
var modOrders2 = await _virtualDbContext.Set<SysUserMod>().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<SysUserMod>().ToListAsync();
Assert.Equal(1000, mods.Count);
var modOrders1 = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Age).ToListAsync();
int ascAge = 1;
foreach (var sysUserMod in modOrders1)
{
Assert.Equal(ascAge, sysUserMod.Age);
ascAge++;
}
var modOrders2 = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Age).ToListAsync();
int descAge = 1000;
foreach (var sysUserMod in modOrders2)
{
Assert.Equal(descAge, sysUserMod.Age);
descAge--;
}
var pageResult = await _virtualDbContext.Set<SysUserMod>().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 ToList_Join_Test()
{
var list = await (from u in _virtualDbContext.Set<SysUserMod>()
join salary in _virtualDbContext.Set<SysUserSalary>()
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<SysUserMod>().Where(o => o.Id == "300")
join salary in _virtualDbContext.Set<SysUserSalary>()
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");
}
[Fact]
public async Task ToList_OrderBy_Asc_Desc_Test()
{
var modascs = await _virtualDbContext.Set<SysUserMod>().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<SysUserMod>().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<SysUserMod>().Where(o => new List<string> { "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<SysUserMod>().Where(o => o.Id == id.ToString()).ToListAsync();
Assert.Single(mods);
var mods1 = await _virtualDbContext.Set<SysUserMod>().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 mods = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id != "3").ToListAsync();
Assert.Equal(999, mods.Count);
Assert.DoesNotContain(mods, o => o.Id == "3");
}
[Fact]
public async Task ToList_Id_Not_Eq_Skip_Test()
{
var mods = await _virtualDbContext.Set<SysUserMod>().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<SysUserMod>().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<SysUserMod>().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 mods = await _virtualDbContext.Set<SysUserMod>().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<SysUserMod>().Where(o => o.Name == "name_1001").ToListAsync();
Assert.Empty(mods);
}
[Fact]
public async Task FirstOrDefault_Order_By_Id_Test()
{
var sysUserModAge = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Age).FirstOrDefaultAsync();
Assert.True(sysUserModAge != null && sysUserModAge.Id == "1");
var sysUserModAgeDesc = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Age).FirstOrDefaultAsync();
Assert.True(sysUserModAgeDesc != null && sysUserModAgeDesc.Id == "1000");
var sysUserMod = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Id).FirstOrDefaultAsync();
Assert.True(sysUserMod != null && sysUserMod.Id == "1");
var sysUserModDesc = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Id).FirstOrDefaultAsync();
Assert.True(sysUserModDesc != null && sysUserModDesc.Id == "999");
}
[Fact]
public async Task FirstOrDefault2()
{
var sysUserMod = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id == "1").FirstOrDefaultAsync();
Assert.NotNull(sysUserMod);
var userMod = _virtualDbContext.Set<SysUserMod>().Find("1");
Assert.Equal(sysUserMod, userMod);
Assert.True(sysUserMod.Id == "1");
var user198 = await _virtualDbContext.Set<SysUserMod>().FirstOrDefaultAsync(o => o.Id == "198");
Assert.True(user198.Id == "198");
var userId198 = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id == "198").Select(o => o.Id).FirstOrDefaultAsync();
Assert.Equal(userId198, "198");
}
[Fact]
public async Task FirstOrDefault3()
{
var sysUserMod = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_2").FirstOrDefaultAsync();
Assert.NotNull(sysUserMod);
Assert.Equal("2", sysUserMod.Id);
}
[Fact]
public async Task FirstOrDefault4()
{
var sysUserMod = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id != "1").FirstOrDefaultAsync();
Assert.NotNull(sysUserMod);
Assert.True(sysUserMod.Id != "1");
}
[Fact]
public async Task FirstOrDefault5()
{
var sysUserMod = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_1001").FirstOrDefaultAsync();
Assert.Null(sysUserMod);
}
[Fact]
public async Task Count_Test()
{
var a = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_1000").CountAsync();
Assert.Equal(1, a);
var b = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name != "name_1000").CountAsync();
Assert.Equal(999, b);
}
[Fact]
public async Task Sum_Test()
{
var a = await _virtualDbContext.Set<SysUserMod>().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<SysUserMod>().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<SysUserMod>().MaxAsync(o => o.Age);
Assert.Equal(1000, a);
var b = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name != "name_1000").MaxAsync(o => o.Age);
Assert.Equal(999, b);
var c = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Age < 500).MaxAsync(o => o.Age);
Assert.Equal(499, c);
var e = await _virtualDbContext.Set<SysUserMod>().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<SysUserMod>().Where(o => o.Id == "300")
join salary in _virtualDbContext.Set<SysUserSalary>()
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<SysUserMod>().MinAsync(o => o.Age);
Assert.Equal(1, a);
var b = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name != "name_1").MinAsync(o => o.Age);
Assert.Equal(2, b);
var c = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Age > 500).MinAsync(o => o.Age);
Assert.Equal(501, c);
var e = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Age >= 500).MinAsync(o => o.Age);
Assert.Equal(500, e);
}
[Fact]
public async Task Any_Test()
{
var a = await _virtualDbContext.Set<SysUserMod>().AnyAsync(o => o.Age == 100);
Assert.True(a);
var b = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name != "name_1").AnyAsync(o => o.Age == 1);
Assert.False(b);
var c = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Age > 500).AnyAsync(o => o.Age <= 500);
Assert.False(c);
var e = await _virtualDbContext.Set<SysUserMod>().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<SysUserSalary>()
.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_API_Test()
// {
// var ids = new[] {"200", "300"};
// var dateOfMonths = new[] {202111, 202110};
// var group = await _virtualDbContext.Set<SysUserSalary>()
// .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth))
// .ShardingGroupByAsync(g => new {UId = g.UserId}, 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)
// });
// 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);
// }
}
}

View File

@ -0,0 +1,27 @@
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Test6x.Domain.Entities;
using ShardingCore.VirtualRoutes.Mods;
namespace ShardingCore.Test6x.Shardings
{
/*
* @Author: xjm
* @Description:
* @Date: Thursday, 14 January 2021 15:39:27
* @Email: 326308290@qq.com
*/
public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUserMod>
{
protected override bool EnableHintRoute => true;
public SysUserModVirtualTableRoute() : base(2,3)
{
}
public override void Configure(EntityMetadataTableBuilder<SysUserMod> builder)
{
builder.ShardingProperty(o => o.Id);
builder.TableSeparator("_");
}
}
}

View File

@ -0,0 +1,80 @@
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.Test6x.Domain.Entities;
namespace ShardingCore.Test6x.Shardings
{
/*
* @Author: xjm
* @Description:
* @Date: Monday, 01 February 2021 15:54:55
* @Email: 326308290@qq.com
*/
public class SysUserSalaryVirtualTableRoute:AbstractShardingOperatorVirtualTableRoute<SysUserSalary,int>
{
protected override int ConvertToShardingKey(object shardingKey)
{
return Convert.ToInt32(shardingKey);
}
public override string ShardingKeyToTail(object shardingKey)
{
var time = ConvertToShardingKey(shardingKey);
return TimeFormatToTail(time);
}
public override List<string> GetAllTails()
{
var beginTime = new DateTime(2020, 1, 1);
var endTime = new DateTime(2021, 12, 1);
var list = new List<string>(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}";
}
protected override Expression<Func<string, bool>> 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<SysUserSalary> builder)
{
builder.ShardingProperty(o => o.DateOfMonth);
}
}
}

View File

@ -0,0 +1,141 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ShardingCore.Bootstrapers;
using ShardingCore.Test6x.Domain.Entities;
using ShardingCore.Test6x.Shardings;
namespace ShardingCore.Test6x
{
/*
* @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();
});
// // 自定义 host 构建
public void ConfigureHost(IHostBuilder hostBuilder)
{
hostBuilder
.ConfigureAppConfiguration(builder =>
{
builder.AddJsonFile("Configs/DbConfig.json");
//builder.AddJsonFile("Configs/MacDbConfig.json");
});
}
// 支持的形式:
// ConfigureServices(IServiceCollection services)
// ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
// ConfigureServices(HostBuilderContext hostBuilderContext, IServiceCollection services)
public void ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
{
services.AddShardingDbContext<ShardingDefaultDbContext>((conn, o) =>
o.UseSqlServer(conn).UseLoggerFactory(efLogger))
.Begin(o =>
{
//o.CreateShardingTableOnStart = true;
//o.EnsureCreatedWithOutShardingTable = true;
o.AutoTrackEntity = true;
})
.AddShardingTransaction((connection, builder) =>
builder.UseSqlServer(connection).UseLoggerFactory(efLogger))
.AddDefaultDataSource("ds0",hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"])
.AddShardingTableRoute(op =>
{
op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
op.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
}).End();
// services.AddShardingDbContext<ShardingDefaultDbContext, DefaultDbContext>(o => o.UseMySql(hostBuilderContext.Configuration.GetSection("MySql")["ConnectionString"],new MySqlServerVersion("5.7.15"))
// ,op =>
// {
// op.EnsureCreatedWithOutShardingTable = true;
// op.CreateShardingTableOnStart = true;
// op.UseShardingOptionsBuilder((connection, builder) => builder.UseMySql(connection,new MySqlServerVersion("5.7.15")).UseLoggerFactory(efLogger),
// (conStr,builder)=> builder.UseMySql(conStr,new MySqlServerVersion("5.7.15")).UseLoggerFactory(efLogger));
// op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
// op.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
// });
}
// 可以添加要用到的方法参数,会自动从注册的服务中获取服务实例,类似于 asp.net core 里 Configure 方法
public void Configure(IServiceProvider serviceProvider)
{
var shardingBootstrapper = serviceProvider.GetService<IShardingBootstrapper>();
shardingBootstrapper.Start();
// 有一些测试数据要初始化可以放在这里
InitData(serviceProvider).GetAwaiter().GetResult();
}
/// <summary>
/// 添加种子数据
/// </summary>
/// <param name="serviceProvider"></param>
/// <returns></returns>
private async Task InitData(IServiceProvider serviceProvider)
{
using (var scope = serviceProvider.CreateScope())
{
var virtualDbContext = scope.ServiceProvider.GetService<ShardingDefaultDbContext>();
if (!await virtualDbContext.Set<SysUserMod>().AnyAsync())
{
var ids = Enumerable.Range(1, 1000);
var userMods = new List<SysUserMod>();
var userSalaries = new List<SysUserSalary>();
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)
});
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++;
}
}
using (var tran = virtualDbContext.Database.BeginTransaction())
{
await virtualDbContext.AddRangeAsync(userMods);
await virtualDbContext.AddRangeAsync(userSalaries);
await virtualDbContext.SaveChangesAsync();
tran.Commit();
}
}
}
}
}
}