修复[#214] 发布6.8.0.3

This commit is contained in:
xuejiaming 2022-10-31 23:19:33 +08:00
parent 9048048dd7
commit 9485ae03c1
14 changed files with 160 additions and 39 deletions

View File

@ -1,6 +1,6 @@
:start
::定义版本
set SHARDINGCORE=6.8.0.2
set SHARDINGCORE=6.8.0.3
::删除所有bin与obj下的文件
@echo off

View File

@ -5,6 +5,7 @@ using Sample.MySql.Domain.Entities;
using Sample.MySql.multi;
using Sample.MySql.Shardings;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
using ShardingCore.Extensions.ShardingQueryableExtensions;
using ShardingCore.Helpers;
@ -85,6 +86,11 @@ namespace Sample.MySql.Controllers
// Console.WriteLine("------------");
// using (var tran = _defaultTableDbContext.Database.BeginTransaction())
// {
SysUserMod? resultX123 = await _defaultTableDbContext.Set<SysUserMod>()
.Where(o => o.Id == "2").FirstOrDefaultAsync();
_defaultTableDbContext.Update(resultX123);
_defaultTableDbContext.SaveChanges();
var resultX1 = await _defaultTableDbContext.Set<SysUserMod>()
.Where(o => o.Id == "2" || o.Id == "3").GroupBy(o => new { o.Id,o.Name })
.Select(o => new

View File

@ -19,6 +19,13 @@ namespace Sample.MySql.DbContexts
//ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
//Database.SetCommandTimeout(30000);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseLazyLoadingProxies();
}
private readonly MethodInfo? _configureGlobalFiltersMethodInfo =
typeof(DefaultShardingDbContext).GetMethod(nameof(ConfigureGlobalFilters), BindingFlags.Instance | BindingFlags.NonPublic);

View File

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

View File

@ -103,6 +103,7 @@ namespace Sample.MySql
o.AddShardingDataSourceRoute<SysUserModVirtualDataSourceRoute>();
}).UseConfig(o =>
{
o.UseEntityFrameworkCoreProxies = true;
o.ThrowIfQueryRouteNotMatch = false;
o.AutoUseWriteConnectionStringAfterWriteDb = true;
o.UseShardingQuery((conStr, builder) =>

View File

@ -16,13 +16,16 @@ namespace ShardingCore.Core.EntityMetadatas
/// 分表或者分库对象的元数据信息记录对象在ShardingCore框架下的一些简单的信息
/// </summary>
public class EntityMetadata
{private const string QueryFilter = "QueryFilter";
{
private const string QueryFilter = "QueryFilter";
public EntityMetadata(Type entityType)
{
EntityType = entityType;
ShardingDataSourceProperties = new Dictionary<string, PropertyInfo>();
ShardingTableProperties = new Dictionary<string, PropertyInfo>();
}
/// <summary>
/// 分表类型 sharding entity type
/// </summary>
@ -37,10 +40,12 @@ namespace ShardingCore.Core.EntityMetadatas
/// 是否分表
/// </summary>
public bool IsMultiTableMapping => null != ShardingTableProperty;
/// <summary>
/// 分库字段
/// </summary>
public PropertyInfo ShardingDataSourceProperty { get; private set; }
/// <summary>
/// 分库所有字段包括 ShardingDataSourceProperty
/// </summary>
@ -49,37 +54,39 @@ namespace ShardingCore.Core.EntityMetadatas
/// <summary>
/// 启动时是否建表 auto create data source when start app
/// </summary>
public bool? AutoCreateDataSourceTable { get; set; }
public bool? AutoCreateDataSourceTable { get; set; }
/// <summary>
/// 分表字段 sharding table property
/// </summary>
public PropertyInfo ShardingTableProperty { get; private set; }
/// <summary>
/// 分表所有字段包括 ShardingTableProperty
/// </summary>
public IDictionary<string, PropertyInfo> ShardingTableProperties { get;}
public IDictionary<string, PropertyInfo> ShardingTableProperties { get; }
/// <summary>
/// 启动时是否建表 auto create table when start app
/// </summary>
public bool? AutoCreateTable { get; set; }
public bool? AutoCreateTable { get; set; }
/// <summary>
/// 分表隔离器 table sharding tail prefix
/// </summary>
public string TableSeparator { get; private set; } = "_";
/// <summary>
/// 逻辑表名
/// </summary>
public string LogicTableName { get; private set; }
/// <summary>
/// 主键
/// </summary>
public IReadOnlyList<PropertyInfo> PrimaryKeyProperties { get; private set; }
/**
* efcore query filter
*/
@ -93,14 +100,14 @@ namespace ShardingCore.Core.EntityMetadatas
public void SetEntityModel(IEntityType dbEntityType)
{
LogicTableName = dbEntityType.GetEntityTypeTableName();
QueryFilterExpression= dbEntityType.GetAnnotations().FirstOrDefault(o=>o.Name== QueryFilter)?.Value as LambdaExpression;
QueryFilterExpression =
dbEntityType.GetAnnotations().FirstOrDefault(o => o.Name == QueryFilter)?.Value as LambdaExpression;
PrimaryKeyProperties = dbEntityType.FindPrimaryKey()?.Properties?.Select(o => o.PropertyInfo)?.ToList() ??
new List<PropertyInfo>();
IsSingleKey=PrimaryKeyProperties.Count == 1;
IsSingleKey = PrimaryKeyProperties.Count == 1;
}
/// <summary>
/// 设置分库字段
/// </summary>
@ -109,10 +116,12 @@ namespace ShardingCore.Core.EntityMetadatas
{
Check.NotNull(propertyInfo, nameof(propertyInfo));
if (ShardingDataSourceProperties.ContainsKey(propertyInfo.Name))
throw new ShardingCoreConfigException($"same sharding data source property name:[{propertyInfo.Name}] don't repeat add");
throw new ShardingCoreConfigException(
$"same sharding data source property name:[{propertyInfo.Name}] don't repeat add");
ShardingDataSourceProperty = propertyInfo;
ShardingDataSourceProperties.Add(propertyInfo.Name, propertyInfo);
}
/// <summary>
/// 添加额外分表字段
/// </summary>
@ -121,9 +130,11 @@ namespace ShardingCore.Core.EntityMetadatas
public void AddExtraSharingDataSourceProperty(PropertyInfo propertyInfo)
{
if (ShardingDataSourceProperties.ContainsKey(propertyInfo.Name))
throw new ShardingCoreConfigException($"same sharding data source property name:[{propertyInfo.Name}] don't repeat add");
throw new ShardingCoreConfigException(
$"same sharding data source property name:[{propertyInfo.Name}] don't repeat add");
ShardingDataSourceProperties.Add(propertyInfo.Name, propertyInfo);
}
/// <summary>
/// 设置分表字段
/// </summary>
@ -132,10 +143,12 @@ namespace ShardingCore.Core.EntityMetadatas
{
Check.NotNull(propertyInfo, nameof(propertyInfo));
if (ShardingTableProperties.ContainsKey(propertyInfo.Name))
throw new ShardingCoreConfigException($"same sharding table property name:[{propertyInfo.Name}] don't repeat add");
throw new ShardingCoreConfigException(
$"same sharding table property name:[{propertyInfo.Name}] don't repeat add");
ShardingTableProperty = propertyInfo;
ShardingTableProperties.Add(propertyInfo.Name, propertyInfo);
}
/// <summary>
/// 添加额外分表字段
/// </summary>
@ -144,7 +157,8 @@ namespace ShardingCore.Core.EntityMetadatas
public void AddExtraSharingTableProperty(PropertyInfo propertyInfo)
{
if (ShardingTableProperties.ContainsKey(propertyInfo.Name))
throw new ShardingCoreConfigException($"same sharding table property name:[{propertyInfo.Name}] don't repeat add");
throw new ShardingCoreConfigException(
$"same sharding table property name:[{propertyInfo.Name}] don't repeat add");
ShardingTableProperties.Add(propertyInfo.Name, propertyInfo);
}
@ -156,6 +170,7 @@ namespace ShardingCore.Core.EntityMetadatas
{
TableSeparator = separator;
}
/// <summary>
/// 启动时检查分库信息是否完整
/// </summary>
@ -165,11 +180,13 @@ namespace ShardingCore.Core.EntityMetadatas
{
throw new ShardingCoreException($"not found entity:{EntityType} configure");
}
if(ShardingDataSourceProperty==null)
if (ShardingDataSourceProperty == null)
{
throw new ShardingCoreException($"not found entity:{EntityType} configure sharding property");
}
}
/// <summary>
/// 启动时检查分表信息是否完整
/// </summary>
@ -179,11 +196,13 @@ namespace ShardingCore.Core.EntityMetadatas
{
throw new ShardingCoreException($"not found entity:{EntityType} configure");
}
if (ShardingTableProperty == null)
{
throw new ShardingCoreException($"not found entity:{EntityType} configure sharding property");
}
}
/// <summary>
/// 启动时检查对象信息是否完整
/// </summary>
@ -195,6 +214,7 @@ namespace ShardingCore.Core.EntityMetadatas
throw new ShardingCoreException($"not found entity:{EntityType} configure");
}
}
protected bool Equals(EntityMetadata other)
{
return Equals(EntityType, other.EntityType);
@ -213,4 +233,4 @@ namespace ShardingCore.Core.EntityMetadatas
return (EntityType != null ? EntityType.GetHashCode() : 0);
}
}
}
}

View File

@ -12,6 +12,11 @@ namespace ShardingCore.Core.ShardingConfigurations
/// </summary>
public class ShardingConfigOptions
{
/// <summary>
/// 是否使用代理模式
/// </summary>
public bool UseEntityFrameworkCoreProxies { get; set; } = false;
/// <summary>
/// 写操作数据库后自动使用写库链接防止读库链接未同步无法查询到数据
/// </summary>

View File

@ -18,5 +18,6 @@ namespace ShardingCore.Core.TrackerManagers
bool AddDbContextModel(Type entityType,bool hasKey);
bool EntityUseTrack(Type entityType);
bool IsDbContextModel(Type entityType);
Type TranslateEntityType(Type entityType);
}
}

View File

@ -4,6 +4,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.ShardingConfigurations;
using ShardingCore.Exceptions;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Core.TrackerManagers
@ -15,9 +17,15 @@ namespace ShardingCore.Core.TrackerManagers
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class TrackerManager: ITrackerManager
public class TrackerManager : ITrackerManager
{
private readonly ConcurrentDictionary<Type,bool> _dbContextModels = new ();
private readonly ShardingConfigOptions _shardingConfigOptions;
private readonly ConcurrentDictionary<Type, bool> _dbContextModels = new();
public TrackerManager(ShardingConfigOptions shardingConfigOptions)
{
_shardingConfigOptions = shardingConfigOptions;
}
public bool AddDbContextModel(Type entityType, bool hasKey)
{
@ -26,16 +34,66 @@ namespace ShardingCore.Core.TrackerManagers
public bool EntityUseTrack(Type entityType)
{
if (!_dbContextModels.TryGetValue(entityType, out var hasKey))
if (_dbContextModels.TryGetValue(entityType, out var hasKey))
{
return false;
return hasKey;
}
return hasKey;
if (_shardingConfigOptions.UseEntityFrameworkCoreProxies && entityType.BaseType != null)
{
if (_dbContextModels.TryGetValue(entityType.BaseType, out hasKey))
{
return hasKey;
}
}
return false;
}
public bool IsDbContextModel(Type entityType)
{
return _dbContextModels.ContainsKey(entityType);
if (_dbContextModels.ContainsKey(entityType))
{
return true;
}
if (_shardingConfigOptions.UseEntityFrameworkCoreProxies && entityType.BaseType != null)
{
return _dbContextModels.ContainsKey(entityType.BaseType);
}
return false;
}
public Type TranslateEntityType(Type entityType)
{
if (!_dbContextModels.ContainsKey(entityType))
{
if (_shardingConfigOptions.UseEntityFrameworkCoreProxies && entityType.BaseType != null)
{
if (_dbContextModels.ContainsKey(entityType.BaseType))
{
return entityType.BaseType;
}
}
}
return entityType;
}
//
// public Type GetEntityType(Type entityType)
// {
// if (_dbContextModels.ContainsKey(entityType))
// {
// return entityType;
// }
//
// if (entityType.BaseType != null&&_dbContextModels.ContainsKey(entityType.BaseType))
// {
// return entityType.BaseType;
// }
// throw new ShardingCoreInvalidOperationException($"entity type:{entityType.FullName} not found");
// }
}
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.ShardingEnumerableQueries;
using ShardingCore.Core.TrackerManagers;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualRoutes.Abstractions;
using ShardingCore.Exceptions;

View File

@ -10,6 +10,7 @@ using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Infrastructure;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Core.TrackerManagers;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualRoutes.Abstractions;
using ShardingCore.Exceptions;
@ -110,6 +111,21 @@ namespace ShardingCore.EFCores
}
}
private ITrackerManager _trackerManager;
protected ITrackerManager TrackerManager
{
get
{
if (null == _trackerManager)
{
_trackerManager = _shardingRuntimeContext.GetTrackerManager();
}
return _trackerManager;
}
}
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
@ -445,7 +461,8 @@ namespace ShardingCore.EFCores
if (primaryKeyValue != null)
{
var dataSourceName = GetDataSourceName(primaryKeyValue);
var tableTail = TableRouteManager.GetTableTail<TEntity>(dataSourceName, primaryKeyValue);
var realEntityType = TrackerManager.TranslateEntityType(typeof(TEntity));
var tableTail = TableRouteManager.GetTableTail<TEntity>(dataSourceName, primaryKeyValue,realEntityType);
var routeTail = _shardingRuntimeContext.GetRouteTailFactory().Create(tableTail);
return _context.GetShareDbContext(dataSourceName, routeTail);
}

View File

@ -22,10 +22,10 @@ namespace ShardingCore.Extensions
public static class DataSourceRouteManagerExtension
{
public static string GetDataSourceName<TEntity>(this IDataSourceRouteManager dataSourceRouteManager,TEntity entity)where TEntity : class
public static string GetDataSourceName<TEntity>(this IDataSourceRouteManager dataSourceRouteManager,TEntity entity,Type realEntityType)where TEntity : class
{
return dataSourceRouteManager.RouteTo(entity.GetType(),
return dataSourceRouteManager.RouteTo(realEntityType,
new ShardingDataSourceRouteConfig(shardingDataSource: entity))[0];
}

View File

@ -68,15 +68,15 @@ namespace ShardingCore.Extensions
public static string GetTableTail<TEntity>(this ITableRouteManager tableRouteManager,string dataSourceName,
TEntity entity) where TEntity : class
TEntity entity,Type realEntityType) where TEntity : class
{
var shardingRouteUnit = tableRouteManager.RouteTo(entity.GetType(),new ShardingTableRouteConfig(shardingTable: entity))[0];
var shardingRouteUnit = tableRouteManager.RouteTo(realEntityType,dataSourceName,new ShardingTableRouteConfig(shardingTable: entity))[0];
return shardingRouteUnit.Tail;
}
public static string GetTableTail<TEntity>(this ITableRouteManager tableRouteManager,string dataSourceName,
object shardingKeyValue) where TEntity : class
object shardingKeyValue,Type realEntityType) where TEntity : class
{
var shardingRouteUnit = tableRouteManager.RouteTo(typeof(TEntity),new ShardingTableRouteConfig(shardingKeyValue: shardingKeyValue))[0];
var shardingRouteUnit = tableRouteManager.RouteTo(realEntityType,dataSourceName,new ShardingTableRouteConfig(shardingKeyValue: shardingKeyValue))[0];
return shardingRouteUnit.Tail;
}
public static bool IsVirtualDataSourceRoute(this Type routeType)

View File

@ -14,6 +14,7 @@ using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Core.DbContextCreator;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Core.ShardingConfigurations;
using ShardingCore.Core.TrackerManagers;
using ShardingCore.Core.VirtualRoutes.Abstractions;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
@ -48,6 +49,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
private readonly ITableRouteManager _tableRouteManager;
private readonly IDbContextCreator _dbContextCreator;
private readonly IRouteTailFactory _routeTailFactory;
private readonly ITrackerManager _trackerManager;
private readonly ActualConnectionStringManager _actualConnectionStringManager;
private readonly IEntityMetadataManager _entityMetadataManager;
@ -77,6 +79,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
_dbContextCreator = _shardingRuntimeContext.GetDbContextCreator();
_entityMetadataManager = _shardingRuntimeContext.GetEntityMetadataManager();
_routeTailFactory = _shardingRuntimeContext.GetRouteTailFactory();
_trackerManager = _shardingRuntimeContext.GetTrackerManager();
var shardingReadWriteManager = _shardingRuntimeContext.GetShardingReadWriteManager();
var shardingProvider = _shardingRuntimeContext.GetShardingProvider();
var loggerFactory = shardingProvider.GetRequiredService<ILoggerFactory>();
@ -133,8 +136,9 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
public DbContext CreateGenericDbContext<TEntity>(TEntity entity) where TEntity : class
{
var dataSourceName = GetDataSourceName(entity);
var tail = GetTableTail(dataSourceName, entity);
var realEntityType = _trackerManager.TranslateEntityType(entity.GetType());
var dataSourceName = GetDataSourceName(entity,realEntityType);
var tail = GetTableTail(dataSourceName, entity,realEntityType);
return CreateDbContext(CreateDbContextStrategyEnum.ShareConnection, dataSourceName,
_routeTailFactory.Create(tail));
@ -145,16 +149,16 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
return _virtualDataSource;
}
private string GetDataSourceName<TEntity>(TEntity entity) where TEntity : class
private string GetDataSourceName<TEntity>(TEntity entity,Type realEntityType) where TEntity : class
{
return _dataSourceRouteManager.GetDataSourceName(entity);
return _dataSourceRouteManager.GetDataSourceName(entity,realEntityType);
}
private string GetTableTail<TEntity>(string dataSourceName, TEntity entity) where TEntity : class
private string GetTableTail<TEntity>(string dataSourceName, TEntity entity,Type realEntityType) where TEntity : class
{
if (!_entityMetadataManager.IsShardingTable(entity.GetType()))
if (!_entityMetadataManager.IsShardingTable(realEntityType))
return string.Empty;
return _tableRouteManager.GetTableTail(dataSourceName, entity);
return _tableRouteManager.GetTableTail(dataSourceName, entity,realEntityType);
}
#endregion