优化构造函数使用让模型提前初始化的方法

This commit is contained in:
xuejiaming 2023-11-24 16:48:20 +08:00
parent 8ed5f09be6
commit 7b92aac822
16 changed files with 134 additions and 60 deletions

View File

@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Sample.MySql.Domain.Entities;
using Sample.MySql.Domain.Maps;
using ShardingCore.Core.DbContextCreator;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.EFCores;
using ShardingCore.Extensions;
@ -23,6 +24,8 @@ namespace Sample.MySql.DbContexts
public DefaultShardingDbContext(DbContextOptions<DefaultShardingDbContext> options) : base(options)
{
RouteTail = RouteTailContextHelper.RouteTail;
Database.SetCommandTimeout(1000);
var key = options.Extensions
.OrderBy(e => e.GetType().Name)
.Select(o =>
@ -30,8 +33,10 @@ namespace Sample.MySql.DbContexts
Console.WriteLine(o.GetType().Name);
return o;
})
.Aggregate(0L, (t, e) => (t * 397) ^ ((long)e.GetType().GetHashCode() * 397) ^ e.Info.GetServiceProviderHashCode());
Console.WriteLine("key:"+key);
.Aggregate(0L,
(t, e) => (t * 397) ^ ((long)e.GetType().GetHashCode() * 397) ^
e.Info.GetServiceProviderHashCode());
Console.WriteLine("key:" + key);
//切记不要在构造函数中使用会让模型提前创建的方法
//ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
//Database.SetCommandTimeout(30000);
@ -49,11 +54,10 @@ namespace Sample.MySql.DbContexts
modelBuilder.ApplyConfiguration(new SysTestMap());
modelBuilder.ApplyConfiguration(new SysUserLogByMonthMap());
modelBuilder.Entity<SysUserLogByMonth>().HasData(new SysUserLogByMonth() { Id = "1", Time = DateTime.Now });
modelBuilder.Entity<SysUserLogByMonth>().HasData(new SysUserLogByMonth() { Id = "1", Time = DateTime.Now });
// modelBuilder.Entity<SysTest>().HasData(new SysTest() { Id = "1", UserId = "123" });
// modelBuilder.Entity<TestMod>().ToTable(nameof(TestMod));
// modelBuilder.Entity<SysTest>().ToTable("xxx");
}
@ -80,7 +84,6 @@ namespace Sample.MySql.DbContexts
return expression;
}
public IRouteTail RouteTail { get; set; }
}
}

View File

@ -39,7 +39,10 @@ namespace ShardingCore.Core.DbContextCreator
var dbContext = _creator(shardingDbContextOptions);
if (dbContext is IShardingTableDbContext shardingTableDbContext)
{
shardingTableDbContext.RouteTail = shardingDbContextOptions.RouteTail;
if (shardingTableDbContext.RouteTail == null)
{
shardingTableDbContext.RouteTail = shardingDbContextOptions.RouteTail;
}
}
_ = dbContext.Model;
return dbContext;

View File

@ -0,0 +1,34 @@
using System;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.ServiceProviders;
namespace ShardingCore.Core.DbContextCreator
{
public class DefaultRouteTailDbContextCreator:IRouteTailDbContextCreator
{
private readonly IDbContextCreator _dbContextCreator;
public DefaultRouteTailDbContextCreator(IDbContextCreator dbContextCreator)
{
_dbContextCreator = dbContextCreator;
}
public DbContext CreateDbContext(DbContext shellDbContext, ShardingDbContextOptions shardingDbContextOptions)
{
try
{
RouteTailContextHelper.RouteTail = shardingDbContextOptions.RouteTail;
return _dbContextCreator.CreateDbContext(shellDbContext,shardingDbContextOptions);
}
finally
{
RouteTailContextHelper.RouteTail = null;
}
}
public DbContext GetShellDbContext(IShardingProvider shardingProvider)
{
return _dbContextCreator.GetShellDbContext(shardingProvider);
}
}
}

View File

@ -1,38 +0,0 @@
// using System;
// using System.Collections.Generic;
// using System.Linq;
// using System.Text;
// using System.Threading.Tasks;
// using Microsoft.EntityFrameworkCore;
// using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
// using ShardingCore.Core.DbContextCreator;
// using ShardingCore.Core.ServiceProviders;
// using ShardingCore.Sharding.Abstractions;
//
// namespace ShardingCore.Core.DbContextCreator
// {
// /// <summary>
// /// dbcontext创建者
// /// </summary>
// /// Author: xjm
// /// Created: 2022/4/2 21:12:17
// /// Email: 326308290@qq.com
// public interface IAsyncDbContextCreator
// {
// /// <summary>
// /// 创建dbcontext
// /// </summary>
// /// <param name="shellDbContext">最外部的dbcontext也就是壳不具备真正的执行</param>
// /// <param name="shardingDbContextOptions">返回dbcontext的配置路由等信息</param>
// /// <returns></returns>
// DbContext CreateDbContext(DbContext shellDbContext, ShardingDbContextOptions shardingDbContextOptions);
// // DbContext CreateDbContext(DbContext shellDbContext, ShardingDbContextOptions shardingDbContextOptions);
//
// /// <summary>
// /// 返回shell db context 框架如何获取db context
// /// </summary>
// /// <param name="shardingProvider"></param>
// /// <returns></returns>
// DbContext GetShellDbContext(IShardingProvider shardingProvider);
// }
// }

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Core.DbContextCreator;
using ShardingCore.Core.ServiceProviders;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Core.DbContextCreator
{
/// <summary>
/// dbcontext创建者
/// </summary>
/// Author: xjm
/// Created: 2022/4/2 21:12:17
/// Email: 326308290@qq.com
public interface IRouteTailDbContextCreator
{
/// <summary>
/// 创建dbcontext
/// </summary>
/// <param name="shellDbContext">最外部的dbcontext也就是壳不具备真正的执行</param>
/// <param name="shardingDbContextOptions">返回dbcontext的配置路由等信息</param>
/// <returns></returns>
DbContext CreateDbContext(DbContext shellDbContext, ShardingDbContextOptions shardingDbContextOptions);
// DbContext CreateDbContext(DbContext shellDbContext, ShardingDbContextOptions shardingDbContextOptions);
/// <summary>
/// 返回shell db context 框架如何获取db context
/// </summary>
/// <param name="shardingProvider"></param>
/// <returns></returns>
DbContext GetShellDbContext(IShardingProvider shardingProvider);
}
}

View File

@ -0,0 +1,21 @@
using System.Threading;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
namespace ShardingCore.Core.DbContextCreator
{
public class RouteTailContextHelper
{
private static AsyncLocal<IRouteTail> _shardingRouteContext = new AsyncLocal<IRouteTail>();
/// <summary>
/// sharding route context use in using code block
/// </summary>
public static IRouteTail RouteTail
{
get => _shardingRouteContext.Value;
set => _shardingRouteContext.Value = value;
}
}
}

View File

@ -45,6 +45,7 @@ namespace ShardingCore.Core.RuntimeContexts
ITrackerManager GetTrackerManager();
IParallelTableManager GetParallelTableManager();
IDbContextCreator GetDbContextCreator();
IRouteTailDbContextCreator GetRouteTailDbContextCreator();
IEntityMetadataManager GetEntityMetadataManager();
// IVirtualDataSourceManager GetVirtualDataSourceManager();
IVirtualDataSource GetVirtualDataSource();

View File

@ -171,6 +171,13 @@ namespace ShardingCore.Core.RuntimeContexts
return _dbContextCreator ??= GetRequiredService<IDbContextCreator>();
}
private IRouteTailDbContextCreator _routeTailDbContextCreator;
public IRouteTailDbContextCreator GetRouteTailDbContextCreator()
{
return _routeTailDbContextCreator ??= GetRequiredService<IRouteTailDbContextCreator>();
}
private IEntityMetadataManager _entityMetadataManager;
public IEntityMetadataManager GetEntityMetadataManager()
@ -345,6 +352,7 @@ namespace ShardingCore.Core.RuntimeContexts
GetTrackerManager();
GetParallelTableManager();
GetDbContextCreator();
GetRouteTailDbContextCreator();
GetEntityMetadataManager();
GetVirtualDataSource();
GetDataSourceRouteManager();

View File

@ -69,7 +69,7 @@ namespace ShardingCore.EFCores
List<MigrateUnit> migrateUnits)
{
var shardingMigrationManager = shardingRuntimeContext.GetShardingMigrationManager();
var dbContextCreator = shardingRuntimeContext.GetDbContextCreator();
var routeTailDbContextCreator = shardingRuntimeContext.GetRouteTailDbContextCreator();
var routeTailFactory = shardingRuntimeContext.GetRouteTailFactory();
var migrateTasks = migrateUnits.Select(migrateUnit =>
{
@ -82,7 +82,7 @@ namespace ShardingCore.EFCores
var dbContextOptions = DynamicShardingHelper.CreateShellDbContextOptions(shardingRuntimeContext,
migrateUnit.DataSourceName);
using (var dbContext = dbContextCreator.CreateDbContext(migrateUnit.ShellDbContext,
using (var dbContext = routeTailDbContextCreator.CreateDbContext(migrateUnit.ShellDbContext,
new ShardingDbContextOptions(dbContextOptions,
routeTailFactory.Create(string.Empty, false))))
{

View File

@ -1,7 +1,10 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using ShardingCore.Core.DbContextCreator;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.EFCores
{

View File

@ -17,10 +17,10 @@ namespace ShardingCore.Extensions
/// Email: 326308290@qq.com
public static class IDbContextCreatorExtension
{
public static DbContext CreateDbContext(this IDbContextCreator dbContextCreator,DbContext mainDbContext, DbContextOptions dbContextOptions,
public static DbContext CreateDbContext(this IRouteTailDbContextCreator routeTailDbContextCreator,DbContext mainDbContext, DbContextOptions dbContextOptions,
IRouteTail routeTail)
{
return dbContextCreator.CreateDbContext(mainDbContext,
return routeTailDbContextCreator.CreateDbContext(mainDbContext,
new ShardingDbContextOptions(dbContextOptions, routeTail));
}
}

View File

@ -91,7 +91,7 @@ namespace ShardingCore.Helpers
private static async Task ExecuteMigrateUnitsAsync(IShardingRuntimeContext shardingRuntimeContext,List<MigrateUnit> migrateUnits,string targetMigration=null,CancellationToken cancellationToken = new CancellationToken())
{
var shardingMigrationManager = shardingRuntimeContext.GetShardingMigrationManager();
var dbContextCreator = shardingRuntimeContext.GetDbContextCreator();
var routeTailDbContextCreator = shardingRuntimeContext.GetRouteTailDbContextCreator();
var routeTailFactory = shardingRuntimeContext.GetRouteTailFactory();
var migrateTasks = migrateUnits.Select(migrateUnit =>
{
@ -104,7 +104,7 @@ namespace ShardingCore.Helpers
var dbContextOptions = CreateShellDbContextOptions(shardingRuntimeContext,
migrateUnit.DataSourceName);
using (var dbContext = dbContextCreator.CreateDbContext(migrateUnit.ShellDbContext,
using (var dbContext = routeTailDbContextCreator.CreateDbContext(migrateUnit.ShellDbContext,
new ShardingDbContextOptions(dbContextOptions,
routeTailFactory.Create(string.Empty, false))))
{

View File

@ -48,7 +48,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
/// <summary>
/// dbcontext 创建接口
/// </summary>
private readonly IDbContextCreator _dbContextCreator;
private readonly IRouteTailDbContextCreator _routeTailDbContextCreator;
/// <summary>
/// 实际的链接字符串管理者 用来提供查询和插入dbcontext的创建链接的获取
@ -110,12 +110,12 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
/// <param name="dataSourceName"></param>
/// <param name="isDefault"></param>
/// <param name="shardingShellDbContext"></param>
/// <param name="dbContextCreator"></param>
/// <param name="routeTailDbContextCreator"></param>
/// <param name="actualConnectionStringManager"></param>
public DataSourceDbContext(string dataSourceName,
bool isDefault,
DbContext shardingShellDbContext,
IDbContextCreator dbContextCreator,
IRouteTailDbContextCreator routeTailDbContextCreator,
ActualConnectionStringManager actualConnectionStringManager)
{
DataSourceName = dataSourceName;
@ -124,7 +124,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
_shardingRuntimeContext = shardingShellDbContext.GetShardingRuntimeContext();
DbContextType = shardingShellDbContext.GetType();
_virtualDataSource = _shardingRuntimeContext.GetVirtualDataSource();
_dbContextCreator = dbContextCreator;
_routeTailDbContextCreator = routeTailDbContextCreator;
_actualConnectionStringManager = actualConnectionStringManager;
}
@ -203,7 +203,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
var cacheKey = routeTail.GetRouteTailIdentity();
if (!_dataSourceDbContexts.TryGetValue(cacheKey, out var dbContext))
{
dbContext = _dbContextCreator.CreateDbContext(_shardingShellDbContext,
dbContext = _routeTailDbContextCreator.CreateDbContext(_shardingShellDbContext,
CreateShareDbContextOptionsBuilder(), routeTail);
_dataSourceDbContexts.Add(cacheKey, dbContext);
ShardingDbTransaction();

View File

@ -54,7 +54,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
private readonly IVirtualDataSource _virtualDataSource;
private readonly IDataSourceRouteManager _dataSourceRouteManager;
private readonly ITableRouteManager _tableRouteManager;
private readonly IDbContextCreator _dbContextCreator;
private readonly IRouteTailDbContextCreator _routeTailDbContextCreator;
private readonly IRouteTailFactory _routeTailFactory;
private readonly ITrackerManager _trackerManager;
private readonly ActualConnectionStringManager _actualConnectionStringManager;
@ -90,7 +90,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
_virtualDataSource = _shardingRuntimeContext.GetVirtualDataSource();
_dataSourceRouteManager = _shardingRuntimeContext.GetDataSourceRouteManager();
_tableRouteManager = _shardingRuntimeContext.GetTableRouteManager();
_dbContextCreator = _shardingRuntimeContext.GetDbContextCreator();
_routeTailDbContextCreator = _shardingRuntimeContext.GetRouteTailDbContextCreator();
_entityMetadataManager = _shardingRuntimeContext.GetEntityMetadataManager();
_routeTailFactory = _shardingRuntimeContext.GetRouteTailFactory();
_trackerManager = _shardingRuntimeContext.GetTrackerManager();
@ -108,7 +108,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
{
return _dbContextCaches.GetOrAdd(dataSourceName,
dsname => new DataSourceDbContext(dsname, _virtualDataSource.IsDefault(dsname), _shardingDbContext,
_dbContextCreator, _actualConnectionStringManager));
_routeTailDbContextCreator, _actualConnectionStringManager));
}
/// <summary>
@ -135,7 +135,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
{
var parallelDbContextOptions = CreateParallelDbContextOptions(dataSourceName, strategy);
dbContext =
_dbContextCreator.CreateDbContext(_shardingDbContext, parallelDbContextOptions, routeTail);
_routeTailDbContextCreator.CreateDbContext(_shardingDbContext, parallelDbContextOptions, routeTail);
dbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
}
if (CreateDbContextAfter != null)

View File

@ -144,6 +144,7 @@ namespace ShardingCore
.TryAddSingleton<IVirtualDataSourceConfigurationParams, SimpleVirtualDataSourceConfigurationParams>();
//分表dbcontext创建
services.TryAddSingleton<IDbContextCreator, ActivatorDbContextCreator<TShardingDbContext>>();
services.TryAddSingleton<IRouteTailDbContextCreator, DefaultRouteTailDbContextCreator>();
services.TryAddSingleton<IDbContextOptionBuilderCreator, ActivatorDbContextOptionBuilderCreator>();

View File

@ -26,7 +26,7 @@
<Compile Include="..\..\src\ShardingCore\**\*.cs" />
<Compile Remove="..\..\src\ShardingCore\obj\**" />
<Compile Remove="..\..\src\ShardingCore\bin\**" />
<Compile Update="..\..\src\ShardingCore\Core\DbContextCreator\IAsyncDbContextCreator.cs">
<Compile Update="..\..\src\ShardingCore\Core\DbContextCreator\IRouteTailDbContextCreator.cs">
<Link>Core\DbContextCreator\IAsyncDbContextCreator.cs</Link>
</Compile>
</ItemGroup>