修复多IShardingRuntimeContext只对应一个ServiceProvider的bug

This commit is contained in:
xuejiaming 2022-07-20 13:44:52 +08:00
parent 3fa09c8237
commit 8729d346a2
33 changed files with 369 additions and 137 deletions

View File

@ -35,7 +35,9 @@ namespace Sample.MySql.Controllers
var resultX = await _defaultTableDbContext.Set<SysUserMod>() var resultX = await _defaultTableDbContext.Set<SysUserMod>()
.Where(o => o.Id == "2" || o.Id == "3").FirstOrDefaultAsync(); .Where(o => o.Id == "2" || o.Id == "3").FirstOrDefaultAsync();
var resultY = await _defaultTableDbContext.Set<SysUserMod>().FirstOrDefaultAsync(o => o.Id == "2" || o.Id == "3"); var resultY = await _defaultTableDbContext.Set<SysUserMod>().FirstOrDefaultAsync(o => o.Id == "2" || o.Id == "3");
var shardingFirstOrDefaultAsyncxxx = await _defaultTableDbContext.Set<SysUserLogByMonth>().Where(o=>o.Time==DateTime.Now).ToListAsync();
var result = await _defaultTableDbContext.Set<SysTest>().AnyAsync(); var result = await _defaultTableDbContext.Set<SysTest>().AnyAsync();
var result22 = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "2"&&o.Name=="ds1").ToListAsync();
var result1 = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "2" || o.Id == "3").ToListAsync(); var result1 = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "2" || o.Id == "3").ToListAsync();
var result2 = await _defaultTableDbContext.Set<SysUserLogByMonth>().Skip(1).Take(10).ToListAsync(); var result2 = await _defaultTableDbContext.Set<SysUserLogByMonth>().Skip(1).Take(10).ToListAsync();
var shardingFirstOrDefaultAsync = await _defaultTableDbContext.Set<SysUserLogByMonth>().ToListAsync(); var shardingFirstOrDefaultAsync = await _defaultTableDbContext.Set<SysUserLogByMonth>().ToListAsync();

View File

@ -5,6 +5,8 @@ using Sample.MySql.Domain.Entities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.EntityFrameworkCore.Internal;
using Sample.MySql.multi;
using ShardingCore.Bootstrappers; using ShardingCore.Bootstrappers;
namespace Sample.MySql namespace Sample.MySql
@ -21,6 +23,8 @@ namespace Sample.MySql
{ {
using (var scope=app.ApplicationServices.CreateScope()) using (var scope=app.ApplicationServices.CreateScope())
{ {
var otherDbContext =scope.ServiceProvider.GetService<OtherDbContext>();
var any = otherDbContext.MyUsers.Any();
var virtualDbContext =scope.ServiceProvider.GetService<DefaultShardingDbContext>(); var virtualDbContext =scope.ServiceProvider.GetService<DefaultShardingDbContext>();
if (!virtualDbContext.Set<SysUserMod>().Any()) if (!virtualDbContext.Set<SysUserMod>().Any())
{ {
@ -51,6 +55,13 @@ namespace Sample.MySql
} }
} }
// using (var scope=app.ApplicationServices.CreateScope())
// {
//
// var virtualDbContext =scope.ServiceProvider.GetService<DefaultShardingDbContext>();
// var any = virtualDbContext.Set<SysUserMod>().Any();
// }
//using (var scope = app.ApplicationServices.CreateScope()) //using (var scope = app.ApplicationServices.CreateScope())
//{ //{
// var dbContext = scope.ServiceProvider.GetService<DefaultShardingDbContext>(); // var dbContext = scope.ServiceProvider.GetService<DefaultShardingDbContext>();

View File

@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.6"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.7">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>

View File

@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Sample.MySql.DbContexts; using Sample.MySql.DbContexts;
using Sample.MySql.Domain.Entities; using Sample.MySql.Domain.Entities;
using Sample.MySql.multi;
using Sample.MySql.Shardings; using Sample.MySql.Shardings;
using ShardingCore; using ShardingCore;
using ShardingCore.Bootstrappers; using ShardingCore.Bootstrappers;
@ -11,6 +12,7 @@ using ShardingCore.Core.RuntimeContexts;
using ShardingCore.EFCores; using ShardingCore.EFCores;
using ShardingCore.Extensions; using ShardingCore.Extensions;
using ShardingCore.Helpers; using ShardingCore.Helpers;
using ShardingCore.Sharding.ReadWriteConfigurations;
using ShardingCore.TableExists; using ShardingCore.TableExists;
using ShardingCore.TableExists.Abstractions; using ShardingCore.TableExists.Abstractions;
@ -37,8 +39,10 @@ namespace Sample.MySql
{ {
public static readonly ILoggerFactory efLogger = LoggerFactory.Create(builder => public static readonly ILoggerFactory efLogger = LoggerFactory.Create(builder =>
{ {
builder.AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information).AddConsole(); builder.AddFilter((category, level) =>
category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information).AddConsole();
}); });
public Startup(IConfiguration configuration) public Startup(IConfiguration configuration)
{ {
Configuration = configuration; Configuration = configuration;
@ -61,52 +65,90 @@ namespace Sample.MySql
// op.AddShardingTableRoute<SysUserModVirtualTableRoute>(); // op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
// op.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>(); // op.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
// }); // });
services.AddMultiShardingDbContext<OtherDbContext>()
.UseRouteConfig(op => { op.AddShardingTableRoute<MyUserRoute>(); })
.UseConfig(o =>
{
o.ThrowIfQueryRouteNotMatch = false;
o.UseShardingQuery((conStr, builder) =>
{
builder.UseMySql(conStr, new MySqlServerVersion(new Version()))
.UseLoggerFactory(efLogger)
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
});
o.UseShardingTransaction((connection, builder) =>
{
builder
.UseMySql(connection, new MySqlServerVersion(new Version()))
.UseLoggerFactory(efLogger)
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
});
o.UseShardingMigrationConfigure(b =>
{
b.ReplaceService<IMigrationsSqlGenerator, ShardingMySqlMigrationsSqlGenerator>();
});
o.AddDefaultDataSource("ds0",
"server=127.0.0.1;port=3306;database=dbdbdx;userid=root;password=root;");
}).AddShardingCore();
services.AddSingleton<IShardingRuntimeContext>(sp => services.AddSingleton<IShardingRuntimeContext>(sp =>
{ {
Stopwatch stopwatch=Stopwatch.StartNew(); Stopwatch stopwatch = Stopwatch.StartNew();
var shardingRuntimeContext = new ShardingRuntimeBuilder<DefaultShardingDbContext>() var shardingRuntimeContext = new ShardingRuntimeBuilder<DefaultShardingDbContext>()
.UseRouteConfig(o => .UseRouteConfig(o =>
{ {
o.AddShardingTableRoute<SysUserLogByMonthRoute>(); o.AddShardingTableRoute<SysUserLogByMonthRoute>();
o.AddShardingTableRoute<SysUserModVirtualTableRoute>(); o.AddShardingTableRoute<SysUserModVirtualTableRoute>();
o.AddShardingDataSourceRoute<SysUserModVirtualDataSourceRoute>(); o.AddShardingDataSourceRoute<SysUserModVirtualDataSourceRoute>();
}).UseConfig(o => }).UseConfig(o =>
{ {
o.ThrowIfQueryRouteNotMatch = false; o.ThrowIfQueryRouteNotMatch = false;
o.UseShardingQuery((conStr,builder)=> o.UseShardingQuery((conStr, builder) =>
{ {
builder.UseMySql(conStr, new MySqlServerVersion(new Version())) builder.UseMySql(conStr, new MySqlServerVersion(new Version()))
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
.UseLoggerFactory(efLogger) .UseLoggerFactory(efLogger)
.EnableSensitiveDataLogging(); .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
}); });
o.UseShardingTransaction((connection, builder) => o.UseShardingTransaction((connection, builder) =>
{ {
builder builder
.UseMySql(connection, new MySqlServerVersion(new Version())). .UseMySql(connection, new MySqlServerVersion(new Version()))
UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
.UseLoggerFactory(efLogger) .UseLoggerFactory(efLogger)
.EnableSensitiveDataLogging(); .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
}); });
o.AddDefaultDataSource("ds0", "server=127.0.0.1;port=3306;database=dbdbd0;userid=root;password=root;"); o.AddDefaultDataSource("ds0",
o.AddExtraDataSource(sp=>new Dictionary<string, string>() "server=127.0.0.1;port=3306;database=dbdbd0;userid=root;password=root;");
o.AddExtraDataSource(sp => new Dictionary<string, string>()
{ {
{"ds1", "server=127.0.0.1;port=3306;database=dbdbd1;userid=root;password=root;"}, { "ds1", "server=127.0.0.1;port=3306;database=dbdbd1;userid=root;password=root;" },
{"ds2", "server=127.0.0.1;port=3306;database=dbdbd2;userid=root;password=root;"} { "ds2", "server=127.0.0.1;port=3306;database=dbdbd2;userid=root;password=root;" }
}); });
o.AddReadWriteSeparation(sp =>
{
return new Dictionary<string, IEnumerable<string>>()
{
{
"ds0",
new[]
{
"server=127.0.0.1;port=3306;database=dbdbd0_0;userid=root;password=root;"
}
}
};
}, defaultEnable: true, readStrategyEnum: ReadStrategyEnum.Loop,
readConnStringGetStrategy: ReadConnStringGetStrategyEnum.LatestEveryTime);
o.UseShardingMigrationConfigure(b => o.UseShardingMigrationConfigure(b =>
{ {
b.ReplaceService<IMigrationsSqlGenerator, ShardingMySqlMigrationsSqlGenerator>(); b.ReplaceService<IMigrationsSqlGenerator, ShardingMySqlMigrationsSqlGenerator>();
}); });
}).ReplaceService<ITableEnsureManager,MySqlTableEnsureManager>(ServiceLifetime.Singleton) })//.ReplaceService<ITableEnsureManager, MySqlTableEnsureManager>(ServiceLifetime.Singleton)
.Build(sp); .Build(sp);
stopwatch.Stop(); stopwatch.Stop();
Console.WriteLine("ShardingRuntimeContext build:"+stopwatch.ElapsedMilliseconds); Console.WriteLine("ShardingRuntimeContext build:" + stopwatch.ElapsedMilliseconds);
return shardingRuntimeContext; return shardingRuntimeContext;
}); });
services.AddDbContext<DefaultShardingDbContext>(ShardingCoreExtension.UseDefaultSharding<DefaultShardingDbContext>); services.AddDbContext<DefaultShardingDbContext>(ShardingCoreExtension
.UseMutliDefaultSharding<DefaultShardingDbContext>);
// services.AddShardingDbContext<DefaultShardingDbContext>() // services.AddShardingDbContext<DefaultShardingDbContext>()
// .AddEntityConfig(o => // .AddEntityConfig(o =>
// { // {
@ -151,29 +193,56 @@ namespace Sample.MySql
{ {
app.UseDeveloperExceptionPage(); app.UseDeveloperExceptionPage();
} }
app.ApplicationServices.UseAutoShardingCreate();
var shardingRuntimeContext = app.ApplicationServices.GetRequiredService<IShardingRuntimeContext>();
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
var entityMetadata = entityMetadataManager.TryGet<SysUserMod>();
using (var scope = app.ApplicationServices.CreateScope())
{
var defaultShardingDbContext = scope.ServiceProvider.GetService<DefaultShardingDbContext>();
// if (defaultShardingDbContext.Database.GetPendingMigrations().Any())
{
defaultShardingDbContext.Database.Migrate();
}
}
app.ApplicationServices.UseAutoTryCompensateTable(12); var shardingRuntimeContextManager = app.ApplicationServices.GetRequiredService<IShardingRuntimeContextManager>();
var shardingRuntimeContexts = shardingRuntimeContextManager.GetAll();
foreach (var keyValuePair in shardingRuntimeContexts)
{
keyValuePair.Value.UseAutoShardingCreate();
keyValuePair.Value.UseAutoTryCompensateTable();
}
// app.ApplicationServices.UseAutoShardingCreate();
// var shardingRuntimeContext = app.ApplicationServices.GetRequiredService<IShardingRuntimeContext>();
// var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
// var entityMetadata = entityMetadataManager.TryGet<SysUserMod>();
// using (var scope = app.ApplicationServices.CreateScope())
// {
// var defaultShardingDbContext = scope.ServiceProvider.GetService<DefaultShardingDbContext>();
// // if (defaultShardingDbContext.Database.GetPendingMigrations().Any())
// {
// try
// {
//
// defaultShardingDbContext.Database.Migrate();
// }
// catch (Exception e)
// {
// }
// }
// }
// using (var scope = app.ApplicationServices.CreateScope())
// {
// var defaultShardingDbContext = scope.ServiceProvider.GetService<OtherDbContext>();
// // if (defaultShardingDbContext.Database.GetPendingMigrations().Any())
// {
// try
// {
//
// defaultShardingDbContext.Database.Migrate();
// }
// catch (Exception e)
// {
// }
// }
// }
//
// app.ApplicationServices.UseAutoTryCompensateTable(12);
app.UseRouting(); app.UseRouting();
app.UseAuthorization(); app.UseAuthorization();
app.UseEndpoints(endpoints => app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
{
endpoints.MapControllers();
});
// for (int i = 1; i < 500; i++) // for (int i = 1; i < 500; i++)
// { // {
// using (var conn = new MySqlConnection( // using (var conn = new MySqlConnection(
@ -187,4 +256,4 @@ namespace Sample.MySql
app.DbSeed(); app.DbSeed();
} }
} }
} }

View File

@ -0,0 +1,8 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace Sample.MySql.multi;
[Table("MyUser")]
public class MyUser
{
public string Id { get; set; }
}

View File

@ -0,0 +1,16 @@
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.VirtualRoutes.Mods;
namespace Sample.MySql.multi;
public class MyUserRoute:AbstractSimpleShardingModKeyStringVirtualTableRoute<MyUser>
{
public MyUserRoute() : base(1, 3)
{
}
public override void Configure(EntityMetadataTableBuilder<MyUser> builder)
{
builder.ShardingProperty(o => o.Id);
}
}

View File

@ -0,0 +1,16 @@
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Sharding;
using ShardingCore.Sharding.Abstractions;
namespace Sample.MySql.multi;
public class OtherDbContext:AbstractShardingDbContext,IShardingTableDbContext
{
public DbSet<MyUser> MyUsers { get; set; }
public OtherDbContext(DbContextOptions<OtherDbContext> options) : base(options)
{
}
public IRouteTail RouteTail { get; set; }
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
namespace ShardingCore.Core.RuntimeContexts
{
public interface IShardingRuntimeContextManager
{
/// <summary>
/// 尝试获取注册的dbcontext type对应的 没有返回null
/// </summary>
/// <param name="dbContextType"></param>
/// <returns></returns>
IShardingRuntimeContext TryGet(Type dbContextType);
IReadOnlyDictionary<Type, IShardingRuntimeContext> GetAll();
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
namespace ShardingCore.Core.RuntimeContexts
{
public class ShardingRuntimeContextManager:IShardingRuntimeContextManager
{
private readonly ImmutableDictionary<Type, IShardingRuntimeContext> _caches;
public ShardingRuntimeContextManager(IEnumerable<IShardingRuntimeContext> shardingRuntimeContexts)
{
_caches = shardingRuntimeContexts.ToImmutableDictionary(o => o.DbContextType, o => o);
}
public IShardingRuntimeContext TryGet(Type dbContextType)
{
if (_caches.TryGetValue(dbContextType, out var shardingRuntimeContext))
{
return shardingRuntimeContext;
}
return null;
}
public IReadOnlyDictionary<Type, IShardingRuntimeContext> GetAll()
{
return _caches;
}
}
}

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -19,15 +20,15 @@ namespace ShardingCore.EFCores.OptionsExtensions
#if EFCORE6 #if EFCORE6
public class ShardingOptionsExtension : IDbContextOptionsExtension public class ShardingOptionsExtension : IDbContextOptionsExtension
{ {
private readonly IShardingRuntimeContext _shardingRuntimeContext; public IShardingRuntimeContext ShardingRuntimeContext { get; }
public ShardingOptionsExtension(IShardingRuntimeContext shardingRuntimeContext) public ShardingOptionsExtension(IShardingRuntimeContext shardingRuntimeContext)
{ {
_shardingRuntimeContext = shardingRuntimeContext; ShardingRuntimeContext = shardingRuntimeContext;
} }
public void ApplyServices(IServiceCollection services) public void ApplyServices(IServiceCollection services)
{ {
services.AddSingleton<IShardingRuntimeContext>(sp => _shardingRuntimeContext); services.AddSingleton<IShardingRuntimeContext>(sp =>ShardingRuntimeContext);
} }
public void Validate(IDbContextOptions options) public void Validate(IDbContextOptions options)
@ -35,15 +36,17 @@ namespace ShardingCore.EFCores.OptionsExtensions
} }
public DbContextOptionsExtensionInfo Info => new ShardingWrapDbContextOptionsExtensionInfo(this); public DbContextOptionsExtensionInfo Info => new ShardingOptionsExtensionInfo(this);
private class ShardingWrapDbContextOptionsExtensionInfo : DbContextOptionsExtensionInfo private class ShardingOptionsExtensionInfo : DbContextOptionsExtensionInfo
{ {
public ShardingWrapDbContextOptionsExtensionInfo(IDbContextOptionsExtension extension) : base(extension) private readonly ShardingOptionsExtension _shardingOptionsExtension;
public ShardingOptionsExtensionInfo(IDbContextOptionsExtension extension) : base(extension)
{ {
_shardingOptionsExtension = (ShardingOptionsExtension)extension;
} }
public override int GetServiceProviderHashCode() => 0; public override int GetServiceProviderHashCode() => _shardingOptionsExtension.ShardingRuntimeContext.GetHashCode();
public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo other) => true; public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo other) => true;
@ -60,15 +63,15 @@ namespace ShardingCore.EFCores.OptionsExtensions
public class ShardingOptionsExtension: IDbContextOptionsExtension public class ShardingOptionsExtension: IDbContextOptionsExtension
{ {
private readonly IShardingRuntimeContext _shardingRuntimeContext; public IShardingRuntimeContext ShardingRuntimeContext { get; }
public ShardingOptionsExtension(IShardingRuntimeContext shardingRuntimeContext) public ShardingOptionsExtension(IShardingRuntimeContext shardingRuntimeContext)
{ {
_shardingRuntimeContext = shardingRuntimeContext; ShardingRuntimeContext = shardingRuntimeContext;
} }
public void ApplyServices(IServiceCollection services) public void ApplyServices(IServiceCollection services)
{ {
services.AddSingleton<IShardingRuntimeContext>(sp => _shardingRuntimeContext); services.AddSingleton<IShardingRuntimeContext>(sp => ShardingRuntimeContext);
} }
public void Validate(IDbContextOptions options) public void Validate(IDbContextOptions options)
@ -76,13 +79,18 @@ namespace ShardingCore.EFCores.OptionsExtensions
} }
public DbContextOptionsExtensionInfo Info => new ShardingWrapDbContextOptionsExtensionInfo(this); public DbContextOptionsExtensionInfo Info => new ShardingOptionsExtensionInfo(this);
private class ShardingWrapDbContextOptionsExtensionInfo : DbContextOptionsExtensionInfo private class ShardingOptionsExtensionInfo : DbContextOptionsExtensionInfo
{ {
public ShardingWrapDbContextOptionsExtensionInfo(IDbContextOptionsExtension extension) : base(extension) { } private readonly ShardingOptionsExtension _shardingOptionsExtension;
public ShardingOptionsExtensionInfo(IDbContextOptionsExtension extension) : base(extension)
{
_shardingOptionsExtension = (ShardingOptionsExtension)extension;
}
public override long GetServiceProviderHashCode() => 0;
public override long GetServiceProviderHashCode() => _shardingOptionsExtension.ShardingRuntimeContext.GetHashCode();
public override void PopulateDebugInfo(IDictionary<string, string> debugInfo) { } public override void PopulateDebugInfo(IDictionary<string, string> debugInfo) { }
@ -96,18 +104,18 @@ namespace ShardingCore.EFCores.OptionsExtensions
public class ShardingOptionsExtension: IDbContextOptionsExtension public class ShardingOptionsExtension: IDbContextOptionsExtension
{ {
private readonly IShardingRuntimeContext _shardingRuntimeContext; public IShardingRuntimeContext ShardingRuntimeContext { get; }
public ShardingOptionsExtension(IShardingRuntimeContext shardingRuntimeContext) public ShardingOptionsExtension(IShardingRuntimeContext shardingRuntimeContext)
{ {
_shardingRuntimeContext = shardingRuntimeContext; ShardingRuntimeContext = shardingRuntimeContext;
} }
public bool ApplyServices(IServiceCollection services) public bool ApplyServices(IServiceCollection services)
{ {
services.AddSingleton<IShardingRuntimeContext>(sp => _shardingRuntimeContext); services.AddSingleton<IShardingRuntimeContext>(sp => ShardingRuntimeContext);
return true; return true;
} }
public long GetServiceProviderHashCode() => 0; public long GetServiceProviderHashCode() => ShardingRuntimeContext.GetHashCode();
public void Validate(IDbContextOptions options) public void Validate(IDbContextOptions options)
{ {

View File

@ -37,14 +37,14 @@ namespace ShardingCore.EFCores
public ShardingInternalDbSet(DbContext context, string entityTypeName) : base(context, entityTypeName) public ShardingInternalDbSet(DbContext context, string entityTypeName) : base(context, entityTypeName)
{ {
_context = (IShardingDbContext)context; _context = (IShardingDbContext)context;
_shardingRuntimeContext = context.GetService<IShardingRuntimeContext>(); _shardingRuntimeContext = context.GetShardingRuntimeContext();
} }
#endif #endif
#if EFCORE2 || EFCORE3 #if EFCORE2 || EFCORE3
public ShardingInternalDbSet(DbContext context) : base(context) public ShardingInternalDbSet(DbContext context) : base(context)
{ {
_context = (IShardingDbContext)context; _context = (IShardingDbContext)context;
_shardingRuntimeContext = context.GetService<IShardingRuntimeContext>(); _shardingRuntimeContext = context.GetShardingRuntimeContext();
} }
#endif #endif

View File

@ -16,7 +16,10 @@ namespace ShardingCore.EFCores
public class ShardingModelCacheKeyFactory : IModelCacheKeyFactory public class ShardingModelCacheKeyFactory : IModelCacheKeyFactory
{ {
public ShardingModelCacheKeyFactory()
{
Console.WriteLine("ShardingModelCacheKeyFactory");
}
public object Create(DbContext context) public object Create(DbContext context)
{ {
return Create(context, false); return Create(context, false);

View File

@ -1,9 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -11,6 +13,7 @@ using ShardingCore.Core;
using ShardingCore.Core.EntityMetadatas; using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.RuntimeContexts; using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions; using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Extensions;
using ShardingCore.Extensions.InternalExtensions; using ShardingCore.Extensions.InternalExtensions;
using ShardingCore.Sharding.Abstractions; using ShardingCore.Sharding.Abstractions;
@ -38,8 +41,7 @@ namespace ShardingCore.EFCores
if (context is IShardingTableDbContext shardingTableDbContext&& shardingTableDbContext.RouteTail !=null&& shardingTableDbContext.RouteTail.IsShardingTableQuery()) if (context is IShardingTableDbContext shardingTableDbContext&& shardingTableDbContext.RouteTail !=null&& shardingTableDbContext.RouteTail.IsShardingTableQuery())
{ {
var shardingRuntimeContext = context.GetShardingRuntimeContext();
var shardingRuntimeContext = context.GetService<IShardingRuntimeContext>();
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
var isMultiEntityQuery = shardingTableDbContext.RouteTail.IsMultiEntityQuery(); var isMultiEntityQuery = shardingTableDbContext.RouteTail.IsMultiEntityQuery();
if (!isMultiEntityQuery) if (!isMultiEntityQuery)

View File

@ -29,6 +29,7 @@ namespace ShardingCore.EFCores
{ {
_shardingDbContext = currentContext.Context as IShardingDbContext ?? _shardingDbContext = currentContext.Context as IShardingDbContext ??
throw new ShardingCoreException("db context operator is not IShardingDbContext"); throw new ShardingCoreException("db context operator is not IShardingDbContext");
Console.WriteLine("ShardingQueryCompiler"+shardingRuntimeContext.DbContextType);
_shardingCompilerExecutor = shardingRuntimeContext.GetShardingCompilerExecutor(); _shardingCompilerExecutor = shardingRuntimeContext.GetShardingCompilerExecutor();
} }

View File

@ -17,6 +17,7 @@ using ShardingCore.Core;
using ShardingCore.Core.EntityMetadatas; using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.RuntimeContexts; using ShardingCore.Core.RuntimeContexts;
using ShardingCore.EFCores; using ShardingCore.EFCores;
using ShardingCore.EFCores.OptionsExtensions;
using ShardingCore.Exceptions; using ShardingCore.Exceptions;
using ShardingCore.Utils; using ShardingCore.Utils;
@ -42,7 +43,7 @@ namespace ShardingCore.Extensions
var contextModel = dbContext.Model as Model; var contextModel = dbContext.Model as Model;
#endif #endif
var shardingRuntimeContext = dbContext.GetRequireService<IShardingRuntimeContext>(); var shardingRuntimeContext = dbContext.GetShardingRuntimeContext();
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
#if EFCORE6 #if EFCORE6
@ -119,7 +120,7 @@ namespace ShardingCore.Extensions
var contextModel = dbContext.Model as Model; var contextModel = dbContext.Model as Model;
#endif #endif
var shardingRuntimeContext = dbContext.GetRequireService<IShardingRuntimeContext>(); var shardingRuntimeContext = dbContext.GetShardingRuntimeContext();
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
#if EFCORE6 #if EFCORE6
@ -327,15 +328,16 @@ namespace ShardingCore.Extensions
//return entry?.Entity; //return entry?.Entity;
} }
public static TService GetRequireService<TService>(this DbContext dbContext) where TService:class public static IShardingRuntimeContext GetShardingRuntimeContext(this DbContext dbContext)
{ {
var service = dbContext.GetService<TService>(); var shardingRuntimeContext = dbContext.GetService<IShardingRuntimeContext>();
if (service == null)
if (shardingRuntimeContext == null)
{ {
throw new ShardingCoreInvalidOperationException($"cant resolve:[{typeof(TService)}]"); throw new ShardingCoreInvalidOperationException($"cant resolve:[{typeof(IShardingRuntimeContext)}],dbcontext:[{dbContext}]");
} }
return service; return shardingRuntimeContext;
} }
} }

View File

@ -30,12 +30,6 @@ namespace ShardingCore.Extensions
return dbContext.GetService<IDbContextServices>().ContextOptions.FindExtension<UnionAllMergeOptionsExtension>() is not null; return dbContext.GetService<IDbContextServices>().ContextOptions.FindExtension<UnionAllMergeOptionsExtension>() is not null;
} }
public static IShardingRuntimeContext GetShardingRuntimeContext(this IShardingDbContext shardingDbContext)
{
return ((DbContext)shardingDbContext).GetRequireService<IShardingRuntimeContext>();
}
/// <summary> /// <summary>
/// 创建共享链接DbConnection /// 创建共享链接DbConnection
/// </summary> /// </summary>

View File

@ -89,7 +89,7 @@ namespace ShardingCore.Extensions
{ {
if (entities.IsEmpty()) if (entities.IsEmpty())
return new Dictionary<string, Dictionary<DbContext, IEnumerable<TEntity>>>(); return new Dictionary<string, Dictionary<DbContext, IEnumerable<TEntity>>>();
var shardingRuntimeContext = shardingDbContext.GetRequireService<IShardingRuntimeContext>(); var shardingRuntimeContext = shardingDbContext.GetShardingRuntimeContext();
var entityType = typeof(TEntity); var entityType = typeof(TEntity);
var routeTailFactory = shardingRuntimeContext.GetRouteTailFactory(); var routeTailFactory = shardingRuntimeContext.GetRouteTailFactory();
var virtualDataSource = shardingDbContext.GetVirtualDataSource(); var virtualDataSource = shardingDbContext.GetVirtualDataSource();
@ -225,7 +225,7 @@ namespace ShardingCore.Extensions
IEnumerable<TEntity> entities) where TShardingDbContext : DbContext, IShardingDbContext IEnumerable<TEntity> entities) where TShardingDbContext : DbContext, IShardingDbContext
where TEntity : class where TEntity : class
{ {
var shardingRuntimeContext = shardingDbContext.GetRequireService<IShardingRuntimeContext>(); var shardingRuntimeContext = shardingDbContext.GetShardingRuntimeContext();
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
if (entityMetadataManager.IsShardingDataSource(typeof(TEntity))) if (entityMetadataManager.IsShardingDataSource(typeof(TEntity)))
throw new ShardingCoreInvalidOperationException(typeof(TEntity).FullName); throw new ShardingCoreInvalidOperationException(typeof(TEntity).FullName);
@ -246,7 +246,7 @@ namespace ShardingCore.Extensions
public static IDictionary<string, IEnumerable<DbContext>> BulkShardingExpression<TShardingDbContext, TEntity>(this TShardingDbContext shardingDbContext, Expression<Func<TEntity, bool>> where) where TEntity : class public static IDictionary<string, IEnumerable<DbContext>> BulkShardingExpression<TShardingDbContext, TEntity>(this TShardingDbContext shardingDbContext, Expression<Func<TEntity, bool>> where) where TEntity : class
where TShardingDbContext : DbContext, IShardingDbContext where TShardingDbContext : DbContext, IShardingDbContext
{ {
var shardingRuntimeContext = shardingDbContext.GetRequireService<IShardingRuntimeContext>(); var shardingRuntimeContext = shardingDbContext.GetShardingRuntimeContext();
var routeTailFactory = shardingRuntimeContext.GetRouteTailFactory(); var routeTailFactory = shardingRuntimeContext.GetRouteTailFactory();
var dataSourceRouteManager = shardingRuntimeContext.GetDataSourceRouteManager(); var dataSourceRouteManager = shardingRuntimeContext.GetDataSourceRouteManager();
var tableRouteManager = shardingRuntimeContext.GetTableRouteManager();// (IVirtualTableManager)ShardingContainer.GetService(typeof(IVirtualTableManager<>).GetGenericType0(shardingDbContext.GetType())); var tableRouteManager = shardingRuntimeContext.GetTableRouteManager();// (IVirtualTableManager)ShardingContainer.GetService(typeof(IVirtualTableManager<>).GetGenericType0(shardingDbContext.GetType()));
@ -289,7 +289,7 @@ namespace ShardingCore.Extensions
public static IEnumerable<DbContext> BulkShardingTableExpression<TShardingDbContext, TEntity>(this TShardingDbContext shardingDbContext, Expression<Func<TEntity, bool>> where) where TEntity : class public static IEnumerable<DbContext> BulkShardingTableExpression<TShardingDbContext, TEntity>(this TShardingDbContext shardingDbContext, Expression<Func<TEntity, bool>> where) where TEntity : class
where TShardingDbContext : DbContext, IShardingDbContext where TShardingDbContext : DbContext, IShardingDbContext
{ {
var shardingRuntimeContext = shardingDbContext.GetRequireService<IShardingRuntimeContext>(); var shardingRuntimeContext = shardingDbContext.GetShardingRuntimeContext();
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();// (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(shardingDbContext.GetType())); var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();// (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(shardingDbContext.GetType()));
if (entityMetadataManager.IsShardingDataSource(typeof(TEntity))) if (entityMetadataManager.IsShardingDataSource(typeof(TEntity)))
throw new ShardingCoreInvalidOperationException(typeof(TEntity).FullName); throw new ShardingCoreInvalidOperationException(typeof(TEntity).FullName);

View File

@ -44,7 +44,7 @@ namespace ShardingCore.Extensions.ShardingPageExtensions
public static async Task<ShardingPagedResult<T>> ToShardingPageAsync<T>(this IQueryable<T> source, int pageIndex, int pageSize) public static async Task<ShardingPagedResult<T>> ToShardingPageAsync<T>(this IQueryable<T> source, int pageIndex, int pageSize)
{ {
var shardingDbContext = GetShardingDbContext(source); var shardingDbContext = GetShardingDbContext(source);
var shardingRuntimeContext = shardingDbContext.GetShardingRuntimeContext(); var shardingRuntimeContext = ((DbContext)shardingDbContext).GetShardingRuntimeContext();
//设置每次获取多少页 //设置每次获取多少页
var take = pageSize <= 0 ? 1 : pageSize; var take = pageSize <= 0 ? 1 : pageSize;
@ -79,7 +79,7 @@ namespace ShardingCore.Extensions.ShardingPageExtensions
public static ShardingPagedResult<T> ToShardingPage<T>(this IQueryable<T> source, int pageIndex, int pageSize) public static ShardingPagedResult<T> ToShardingPage<T>(this IQueryable<T> source, int pageIndex, int pageSize)
{ {
var shardingDbContext = GetShardingDbContext(source); var shardingDbContext = GetShardingDbContext(source);
var shardingRuntimeContext = shardingDbContext.GetShardingRuntimeContext(); var shardingRuntimeContext = ((DbContext)shardingDbContext).GetShardingRuntimeContext();
//设置每次获取多少页 //设置每次获取多少页
var take = pageSize <= 0 ? 1 : pageSize; var take = pageSize <= 0 ? 1 : pageSize;
//设置当前页码最小1 //设置当前页码最小1

View File

@ -58,7 +58,7 @@ namespace ShardingCore.Extensions
/// <param name="readOnly">是否是读数据源</param> /// <param name="readOnly">是否是读数据源</param>
private static void SetReadWriteSeparation(this ISupportShardingReadWrite supportShardingReadWrite, bool readOnly) private static void SetReadWriteSeparation(this ISupportShardingReadWrite supportShardingReadWrite, bool readOnly)
{ {
var shardingRuntimeContext = ((DbContext)supportShardingReadWrite).GetRequireService<IShardingRuntimeContext>(); var shardingRuntimeContext = ((DbContext)supportShardingReadWrite).GetShardingRuntimeContext();
var shardingReadWriteManager =shardingRuntimeContext.GetService<IShardingReadWriteManager>(); var shardingReadWriteManager =shardingRuntimeContext.GetService<IShardingReadWriteManager>();
var shardingReadWriteContext = shardingReadWriteManager.GetCurrent(); var shardingReadWriteContext = shardingReadWriteManager.GetCurrent();
if (shardingReadWriteContext != null) if (shardingReadWriteContext != null)
@ -86,7 +86,7 @@ namespace ShardingCore.Extensions
{ {
if (shardingDbContext.IsUseReadWriteSeparation()) if (shardingDbContext.IsUseReadWriteSeparation())
{ {
var shardingRuntimeContext = shardingDbContext.GetShardingRuntimeContext(); var shardingRuntimeContext = ((DbContext)shardingDbContext).GetShardingRuntimeContext();
var shardingReadWriteManager =shardingRuntimeContext.GetService<IShardingReadWriteManager>(); var shardingReadWriteManager =shardingRuntimeContext.GetService<IShardingReadWriteManager>();
var shardingReadWriteContext = shardingReadWriteManager.GetCurrent(); var shardingReadWriteContext = shardingReadWriteManager.GetCurrent();
if (shardingReadWriteContext != null) if (shardingReadWriteContext != null)

View File

@ -27,7 +27,7 @@ namespace ShardingCore.Sharding.Enumerators.TrackerEnumerators
public AsyncTrackerEnumerator(IShardingDbContext shardingDbContext, IAsyncEnumerator<T> asyncEnumerator) public AsyncTrackerEnumerator(IShardingDbContext shardingDbContext, IAsyncEnumerator<T> asyncEnumerator)
{ {
var shardingRuntimeContext = shardingDbContext.GetShardingRuntimeContext(); var shardingRuntimeContext = ((DbContext)shardingDbContext).GetShardingRuntimeContext();
_shardingDbContext = shardingDbContext; _shardingDbContext = shardingDbContext;
_asyncEnumerator = asyncEnumerator; _asyncEnumerator = asyncEnumerator;
_queryTrack = shardingRuntimeContext.GetQueryTracker(); _queryTrack = shardingRuntimeContext.GetQueryTracker();
@ -70,7 +70,7 @@ namespace ShardingCore.Sharding.Enumerators.TrackerEnumerators
public AsyncTrackerEnumerator(IShardingDbContext shardingDbContext, IAsyncEnumerator<T> asyncEnumerator) public AsyncTrackerEnumerator(IShardingDbContext shardingDbContext, IAsyncEnumerator<T> asyncEnumerator)
{ {
var shardingRuntimeContext = shardingDbContext.GetShardingRuntimeContext(); var shardingRuntimeContext = ((DbContext)shardingDbContext).GetShardingRuntimeContext();
_shardingDbContext = shardingDbContext; _shardingDbContext = shardingDbContext;
_asyncEnumerator = asyncEnumerator; _asyncEnumerator = asyncEnumerator;
_queryTrack = shardingRuntimeContext.GetQueryTracker(); _queryTrack = shardingRuntimeContext.GetQueryTracker();

View File

@ -24,7 +24,7 @@ namespace ShardingCore.Sharding.Enumerators.TrackerEnumerators
public TrackerEnumerator(IShardingDbContext shardingDbContext,IEnumerator<T> enumerator) public TrackerEnumerator(IShardingDbContext shardingDbContext,IEnumerator<T> enumerator)
{ {
var shardingRuntimeContext = ((DbContext)shardingDbContext).GetRequireService<IShardingRuntimeContext>(); var shardingRuntimeContext = ((DbContext)shardingDbContext).GetShardingRuntimeContext();
_shardingDbContext = shardingDbContext; _shardingDbContext = shardingDbContext;
_enumerator = enumerator; _enumerator = enumerator;
_queryTrack = shardingRuntimeContext.GetQueryTracker(); _queryTrack = shardingRuntimeContext.GetQueryTracker();

View File

@ -5,6 +5,7 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using ShardingCore.Extensions; using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.Enumerators; using ShardingCore.Sharding.Enumerators;
using ShardingCore.Sharding.Enumerators.StreamMergeAsync; using ShardingCore.Sharding.Enumerators.StreamMergeAsync;
using ShardingCore.Sharding.MergeEngines.Abstractions; using ShardingCore.Sharding.MergeEngines.Abstractions;

View File

@ -42,7 +42,7 @@ namespace ShardingCore.Sharding.Parsers.Visitors
public ShardingQueryPrepareVisitor(IShardingDbContext shardingDbContext) public ShardingQueryPrepareVisitor(IShardingDbContext shardingDbContext)
{ {
_shardingDbContext = shardingDbContext; _shardingDbContext = shardingDbContext;
_trackerManager =shardingDbContext.GetShardingRuntimeContext() _trackerManager =((DbContext)shardingDbContext).GetShardingRuntimeContext()
.GetTrackerManager(); .GetTrackerManager();
} }
public ShardingPrepareResult GetShardingPrepareResult() public ShardingPrepareResult GetShardingPrepareResult()

View File

@ -124,7 +124,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
DataSourceName = dataSourceName; DataSourceName = dataSourceName;
IsDefault = isDefault; IsDefault = isDefault;
_shardingShellDbContext = shardingShellDbContext; _shardingShellDbContext = shardingShellDbContext;
_shardingRuntimeContext = shardingDbContext.GetShardingRuntimeContext(); _shardingRuntimeContext = shardingShellDbContext.GetShardingRuntimeContext();
DbContextType = shardingShellDbContext.GetType(); DbContextType = shardingShellDbContext.GetType();
_virtualDataSource =shardingDbContext _virtualDataSource =shardingDbContext
.GetVirtualDataSource(); .GetVirtualDataSource();

View File

@ -64,7 +64,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
{ {
_shardingDbContext = shardingDbContext; _shardingDbContext = shardingDbContext;
//初始化 //初始化
_shardingRuntimeContext = shardingDbContext.GetRequireService<IShardingRuntimeContext>(); _shardingRuntimeContext = shardingDbContext.GetShardingRuntimeContext();
_shardingRuntimeContext.GetOrCreateShardingRuntimeModel(shardingDbContext); _shardingRuntimeContext.GetOrCreateShardingRuntimeModel(shardingDbContext);
_virtualDataSource = _shardingRuntimeContext.GetVirtualDataSource(); _virtualDataSource = _shardingRuntimeContext.GetVirtualDataSource();
_dataSourceRouteManager = _shardingRuntimeContext.GetDataSourceRouteManager(); _dataSourceRouteManager = _shardingRuntimeContext.GetDataSourceRouteManager();

View File

@ -55,13 +55,11 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors
if (mergeQueryCompilerContext.IsEnumerableQuery()) if (mergeQueryCompilerContext.IsEnumerableQuery())
{ {
return EnumerableExecute<TResult>(mergeQueryCompilerContext); return EnumerableExecute<TResult>(mergeQueryCompilerContext);
} }
if (typeof(TResult).HasImplementedRawGeneric(typeof(Task<>))) if (typeof(TResult).HasImplementedRawGeneric(typeof(Task<>)))
{ {
return DoExecute<TResult>(mergeQueryCompilerContext, true, cancellationToken); return DoExecute<TResult>(mergeQueryCompilerContext, true, cancellationToken);
} }

View File

@ -101,7 +101,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
public static MergeQueryCompilerContext Create(IQueryCompilerContext queryCompilerContext, QueryCombineResult queryCombineResult, ShardingRouteResult shardingRouteResult) public static MergeQueryCompilerContext Create(IQueryCompilerContext queryCompilerContext, QueryCombineResult queryCombineResult, ShardingRouteResult shardingRouteResult)
{ {
var shardingDbContext = queryCompilerContext.GetShardingDbContext(); var shardingDbContext = queryCompilerContext.GetShardingDbContext();
var shardingRuntimeContext = ((DbContext)shardingDbContext).GetRequireService<IShardingRuntimeContext>(); var shardingRuntimeContext = ((DbContext)shardingDbContext).GetShardingRuntimeContext();
return new MergeQueryCompilerContext(shardingRuntimeContext,queryCompilerContext, queryCombineResult,shardingRouteResult); return new MergeQueryCompilerContext(shardingRuntimeContext,queryCompilerContext, queryCombineResult,shardingRouteResult);
} }
public Dictionary<Type,IQueryable> GetQueryEntities() public Dictionary<Type,IQueryable> GetQueryEntities()

View File

@ -39,7 +39,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
private QueryCompilerContext(IPrepareParseResult prepareParseResult) private QueryCompilerContext(IPrepareParseResult prepareParseResult)
{ {
_shardingRuntimeContext = ((DbContext)prepareParseResult.GetShardingDbContext()).GetRequireService<IShardingRuntimeContext>(); _shardingRuntimeContext = ((DbContext)prepareParseResult.GetShardingDbContext()).GetShardingRuntimeContext();
_shardingDbContext = prepareParseResult.GetShardingDbContext(); _shardingDbContext = prepareParseResult.GetShardingDbContext();
_queryExpression = prepareParseResult.GetNativeQueryExpression(); _queryExpression = prepareParseResult.GetNativeQueryExpression();
_shardingDbContextType = _shardingDbContext.GetType(); _shardingDbContextType = _shardingDbContext.GetType();

View File

@ -93,7 +93,7 @@ namespace ShardingCore.Sharding
RewriteQueryable = rewriteResult.GetRewriteQueryable(); RewriteQueryable = rewriteResult.GetRewriteQueryable();
OptimizeResult = optimizeResult; OptimizeResult = optimizeResult;
_rewriteResult = rewriteResult; _rewriteResult = rewriteResult;
ShardingRuntimeContext = mergeQueryCompilerContext.GetShardingDbContext().GetShardingRuntimeContext(); ShardingRuntimeContext = ((DbContext)mergeQueryCompilerContext.GetShardingDbContext()).GetShardingRuntimeContext();
_routeTailFactory = ShardingRuntimeContext.GetRouteTailFactory(); _routeTailFactory = ShardingRuntimeContext.GetRouteTailFactory();
_trackerManager = ShardingRuntimeContext.GetTrackerManager(); _trackerManager = ShardingRuntimeContext.GetTrackerManager();
_shardingConfigOptions = ShardingRuntimeContext.GetShardingConfigOptions(); _shardingConfigOptions = ShardingRuntimeContext.GetShardingConfigOptions();
@ -289,7 +289,7 @@ namespace ShardingCore.Sharding
public IShardingComparer GetShardingComparer() public IShardingComparer GetShardingComparer()
{ {
return GetShardingDbContext().GetShardingRuntimeContext().GetRequiredService<IShardingComparer>(); return ((DbContext)GetShardingDbContext()).GetShardingRuntimeContext().GetShardingComparer();
} }
/// <summary> /// <summary>

View File

@ -15,9 +15,8 @@ namespace ShardingCore.Core.Internal.Visitors
* @Date: Wednesday, 13 January 2021 11:31:01 * @Date: Wednesday, 13 January 2021 11:31:01
* @Email: 326308290@qq.com * @Email: 326308290@qq.com
*/ */
public abstract class ShardingExpressionVisitor:ExpressionVisitor public abstract class ShardingExpressionVisitor : ExpressionVisitor
{ {
//public object GetFieldValue(Expression expression) //public object GetFieldValue(Expression expression)
//{ //{
// if (expression is ConstantExpression) // if (expression is ConstantExpression)
@ -50,56 +49,67 @@ namespace ShardingCore.Core.Internal.Visitors
return field.GetValue( return field.GetValue(
GetExpressionValue( GetExpressionValue(
e.Expression e.Expression
) ?? throw new InvalidOperationException($"cant get expression value,{e.Expression.ShardingPrint()} may be null reference") ) ?? throw new InvalidOperationException(
$"cant get expression value,{e.Expression.ShardingPrint()} may be null reference")
); );
case MemberExpression e when e.Member is PropertyInfo property: case MemberExpression e when e.Member is PropertyInfo property:
{ {
if (e.Expression == null&&property.DeclaringType==typeof(DateTime)&&property.Name==nameof(DateTime.Now)) if (e.Expression == null)
{ {
return DateTime.Now; if (property.DeclaringType == typeof(DateTime) && property.Name == nameof(DateTime.Now))
} {
else return DateTime.Now;
{ }
return property.GetValue(
GetExpressionValue( if (property.DeclaringType == typeof(DateTimeOffset) &&
e.Expression property.Name == nameof(DateTimeOffset.Now))
)??throw new InvalidOperationException($"cant get expression value,{e.Expression.ShardingPrint()} may be null reference") {
); return DateTimeOffset.Now;
}
} }
return property.GetValue(
GetExpressionValue(
e.Expression
) ?? throw new InvalidOperationException(
$"cant get expression value,{e.Expression.ShardingPrint()} may be null reference")
);
} }
case ListInitExpression e when e.NewExpression.Arguments.Count() == 0: case ListInitExpression e when e.NewExpression.Arguments.Count() == 0:
{
var collection = e.NewExpression.Constructor.Invoke(new object[0]);
foreach (var i in e.Initializers)
{ {
var collection = e.NewExpression.Constructor.Invoke(new object[0]); i.AddMethod.Invoke(
foreach (var i in e.Initializers) collection,
{ i.Arguments
i.AddMethod.Invoke( .Select(
collection, a => GetExpressionValue(a)
i.Arguments )
.Select( .ToArray()
a => GetExpressionValue(a) );
)
.ToArray()
);
}
return collection;
} }
return collection;
}
case NewArrayExpression e when e.NodeType == ExpressionType.NewArrayInit && e.Expressions.Count > 0: case NewArrayExpression e when e.NodeType == ExpressionType.NewArrayInit && e.Expressions.Count > 0:
{
var collection = new List<object>(e.Expressions.Count);
foreach (var arrayItemExpression in e.Expressions)
{ {
var collection = new List<object>(e.Expressions.Count); collection.Add(GetExpressionValue(arrayItemExpression));
foreach (var arrayItemExpression in e.Expressions)
{
collection.Add(GetExpressionValue(arrayItemExpression));
}
return collection;
} }
return collection;
}
case MethodCallExpression e: case MethodCallExpression e:
{ {
var expressionValue = GetExpressionValue(e.Object); var expressionValue = GetExpressionValue(e.Object);
return e.Method.Invoke( return e.Method.Invoke(
expressionValue, expressionValue,
e.Arguments e.Arguments
@ -116,7 +126,8 @@ namespace ShardingCore.Core.Internal.Visitors
default: default:
{ {
if (expression is BinaryExpression binaryExpression&&expression.NodeType == ExpressionType.ArrayIndex) if (expression is BinaryExpression binaryExpression &&
expression.NodeType == ExpressionType.ArrayIndex)
{ {
var index = GetExpressionValue(binaryExpression.Right); var index = GetExpressionValue(binaryExpression.Right);
if (index is int i) if (index is int i)
@ -128,6 +139,7 @@ namespace ShardingCore.Core.Internal.Visitors
} }
} }
} }
//TODO: better messaging //TODO: better messaging
throw new ShardingCoreException("cant get value " + expression); throw new ShardingCoreException("cant get value " + expression);
} }

View File

@ -32,8 +32,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.7" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -91,6 +91,22 @@ namespace ShardingCore
return services.AddShardingConfigure<TShardingDbContext>(); return services.AddShardingConfigure<TShardingDbContext>();
} }
public static ShardingCoreConfigBuilder<TShardingDbContext> AddMultiShardingDbContext<TShardingDbContext>(
this IServiceCollection services,
ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
where TShardingDbContext : DbContext, IShardingDbContext
{
if (contextLifetime == ServiceLifetime.Singleton)
throw new NotSupportedException($"{nameof(contextLifetime)}:{nameof(ServiceLifetime.Singleton)}");
if (optionsLifetime == ServiceLifetime.Singleton)
throw new NotSupportedException($"{nameof(optionsLifetime)}:{nameof(ServiceLifetime.Singleton)}");
services.AddDbContext<TShardingDbContext>(UseMutliDefaultSharding<TShardingDbContext>, contextLifetime,
optionsLifetime);
services.TryAddSingleton<IShardingRuntimeContextManager, ShardingRuntimeContextManager>();
return services.AddShardingConfigure<TShardingDbContext>();
}
public static ShardingCoreConfigBuilder<TShardingDbContext> AddShardingConfigure<TShardingDbContext>( public static ShardingCoreConfigBuilder<TShardingDbContext> AddShardingConfigure<TShardingDbContext>(
this IServiceCollection services) this IServiceCollection services)
where TShardingDbContext : DbContext, IShardingDbContext where TShardingDbContext : DbContext, IShardingDbContext
@ -99,18 +115,36 @@ namespace ShardingCore
return new ShardingCoreConfigBuilder<TShardingDbContext>(services); return new ShardingCoreConfigBuilder<TShardingDbContext>(services);
} }
public static void UseDefaultSharding<TShardingDbContext>(this DbContextOptionsBuilder dbContextOptionsBuilder,IServiceProvider serviceProvider) where TShardingDbContext : DbContext, IShardingDbContext public static void UseDefaultSharding<TShardingDbContext>(this DbContextOptionsBuilder dbContextOptionsBuilder,
IServiceProvider serviceProvider) where TShardingDbContext : DbContext, IShardingDbContext
{ {
var shardingRuntimeContext = serviceProvider.GetRequiredService<IShardingRuntimeContext>(); var shardingRuntimeContext = serviceProvider.GetRequiredService<IShardingRuntimeContext>();
dbContextOptionsBuilder.UseDefaultSharding<TShardingDbContext>(shardingRuntimeContext); dbContextOptionsBuilder.UseDefaultSharding<TShardingDbContext>(shardingRuntimeContext);
} }
public static void UseDefaultSharding<TShardingDbContext>(IServiceProvider serviceProvider, public static void UseDefaultSharding<TShardingDbContext>(IServiceProvider serviceProvider,
DbContextOptionsBuilder dbContextOptionsBuilder) where TShardingDbContext : DbContext, IShardingDbContext DbContextOptionsBuilder dbContextOptionsBuilder) where TShardingDbContext : DbContext, IShardingDbContext
{ {
var shardingRuntimeContext = serviceProvider.GetRequiredService<IShardingRuntimeContext>(); var shardingRuntimeContext = serviceProvider.GetRequiredService<IShardingRuntimeContext>();
dbContextOptionsBuilder.UseDefaultSharding<TShardingDbContext>(shardingRuntimeContext); dbContextOptionsBuilder.UseDefaultSharding<TShardingDbContext>(shardingRuntimeContext);
} }
public static void UseDefaultSharding<TShardingDbContext>(this DbContextOptionsBuilder dbContextOptionsBuilder,IShardingRuntimeContext shardingRuntimeContext) where TShardingDbContext : DbContext, IShardingDbContext
public static void UseMutliDefaultSharding<TShardingDbContext>(IServiceProvider serviceProvider,
DbContextOptionsBuilder dbContextOptionsBuilder) where TShardingDbContext : DbContext, IShardingDbContext
{
var shardingRuntimeContextManager = serviceProvider.GetRequiredService<IShardingRuntimeContextManager>();
var shardingRuntimeContext = shardingRuntimeContextManager.TryGet(typeof(TShardingDbContext));
if (shardingRuntimeContext == null)
{
throw new InvalidOperationException(
$"cant get multi sharding runtime context:[{typeof(TShardingDbContext)}]");
}
dbContextOptionsBuilder.UseDefaultSharding<TShardingDbContext>(shardingRuntimeContext);
}
public static void UseDefaultSharding<TShardingDbContext>(this DbContextOptionsBuilder dbContextOptionsBuilder,
IShardingRuntimeContext shardingRuntimeContext) where TShardingDbContext : DbContext, IShardingDbContext
{ {
var shardingConfigOptions = shardingRuntimeContext.GetShardingConfigOptions(); var shardingConfigOptions = shardingRuntimeContext.GetShardingConfigOptions();
shardingConfigOptions.ShardingMigrationConfigure?.Invoke(dbContextOptionsBuilder); shardingConfigOptions.ShardingMigrationConfigure?.Invoke(dbContextOptionsBuilder);
@ -211,6 +245,7 @@ namespace ShardingCore
.ReplaceService<IRelationalTransactionFactory, .ReplaceService<IRelationalTransactionFactory,
ShardingRelationalTransactionFactory<TShardingDbContext>>(); ShardingRelationalTransactionFactory<TShardingDbContext>>();
} }
public static DbContextOptionsBuilder UseShardingMigrator( public static DbContextOptionsBuilder UseShardingMigrator(
this DbContextOptionsBuilder optionsBuilder) this DbContextOptionsBuilder optionsBuilder)
{ {
@ -221,6 +256,7 @@ namespace ShardingCore
public static DbContextOptionsBuilder UseShardingOptions(this DbContextOptionsBuilder optionsBuilder, public static DbContextOptionsBuilder UseShardingOptions(this DbContextOptionsBuilder optionsBuilder,
IShardingRuntimeContext shardingRuntimeContext) IShardingRuntimeContext shardingRuntimeContext)
{ {
var shardingOptionsExtension = optionsBuilder.CreateOrGetShardingOptionsExtension(shardingRuntimeContext); var shardingOptionsExtension = optionsBuilder.CreateOrGetShardingOptionsExtension(shardingRuntimeContext);
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(shardingOptionsExtension); ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(shardingOptionsExtension);
return optionsBuilder; return optionsBuilder;
@ -240,9 +276,13 @@ namespace ShardingCore
new ShardingWrapOptionsExtension(); new ShardingWrapOptionsExtension();
private static ShardingOptionsExtension CreateOrGetShardingOptionsExtension( private static ShardingOptionsExtension CreateOrGetShardingOptionsExtension(
this DbContextOptionsBuilder optionsBuilder, IShardingRuntimeContext shardingRuntimeContext) this DbContextOptionsBuilder optionsBuilder, IShardingRuntimeContext shardingRuntimeContext) =>
=> optionsBuilder.Options.FindExtension<ShardingOptionsExtension>() ?? optionsBuilder.Options.FindExtension<ShardingOptionsExtension>() ??
new ShardingOptionsExtension(shardingRuntimeContext); new ShardingOptionsExtension(shardingRuntimeContext);
// private static CoreOptionsExtension CreateOrGetCoreOptionsExtension(
// this DbContextOptionsBuilder optionsBuilder) =>
// optionsBuilder.Options.FindExtension<CoreOptionsExtension>() ??
// new CoreOptionsExtension();
public static DbContextOptionsBuilder UseInnerDbContextSharding(this DbContextOptionsBuilder optionsBuilder) public static DbContextOptionsBuilder UseInnerDbContextSharding(this DbContextOptionsBuilder optionsBuilder)
{ {

View File

@ -41,8 +41,8 @@
<Compile Remove="..\..\src\ShardingCore\ShardingTableConfig.cs" /> <Compile Remove="..\..\src\ShardingCore\ShardingTableConfig.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.26" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.27" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.26" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.27" />
</ItemGroup> </ItemGroup>
</Project> </Project>