优化针对试图的处理

This commit is contained in:
xuejiaming 2023-03-22 11:37:08 +08:00
parent eebbbef46d
commit 2253b0f4f7
4 changed files with 85 additions and 46 deletions

View File

@ -21,12 +21,15 @@ namespace ShardingCore.Core.EntityMetadatas
{
private readonly ShardingConfigOptions _shardingConfigOptions;
private readonly ConcurrentDictionary<Type, EntityMetadata> _caches = new();
private readonly ConcurrentDictionary<string/*logic table name*/, List<EntityMetadata>> _logicTableCaches = new();
private readonly ConcurrentDictionary<string /*logic table name*/, List<EntityMetadata>> _logicTableCaches =
new();
public DefaultEntityMetadataManager(ShardingConfigOptions shardingConfigOptions)
{
_shardingConfigOptions = shardingConfigOptions;
}
public bool AddEntityMetadata(EntityMetadata entityMetadata)
{
return _caches.TryAdd(entityMetadata.EntityType, entityMetadata);
@ -48,7 +51,7 @@ namespace ShardingCore.Core.EntityMetadatas
{
if (!_caches.TryGetValue(entityType, out var entityMetadata))
return false;
return entityMetadata.IsMultiTableMapping&&!entityMetadata.IsMultiDataSourceMapping;
return entityMetadata.IsMultiTableMapping && !entityMetadata.IsMultiDataSourceMapping;
}
/// <summary>
@ -67,7 +70,7 @@ namespace ShardingCore.Core.EntityMetadatas
{
if (!_caches.TryGetValue(entityType, out var entityMetadata))
return false;
return entityMetadata.IsMultiDataSourceMapping&&!entityMetadata.IsMultiTableMapping;
return entityMetadata.IsMultiDataSourceMapping && !entityMetadata.IsMultiTableMapping;
}
/// <summary>
@ -88,6 +91,7 @@ namespace ShardingCore.Core.EntityMetadatas
{
return metadata;
}
return null;
}
@ -124,50 +128,54 @@ namespace ShardingCore.Core.EntityMetadatas
{
var propertyName = metadataProperty.Key;
var property = efEntityType.GetProperty(propertyName);
if (property.ValueGenerated!=ValueGenerated.Never)
if (property.ValueGenerated != ValueGenerated.Never)
{
throw new ShardingCoreConfigException($"sharding data source key:{propertyName} is not {nameof(ValueGenerated)}.{nameof(ValueGenerated.Never)}");
throw new ShardingCoreConfigException(
$"sharding data source key:{propertyName} is not {nameof(ValueGenerated)}.{nameof(ValueGenerated.Never)}");
}
}
}
if (metadata.IsMultiTableMapping)
{
foreach (var metadataProperty in metadata.ShardingTableProperties)
{
var propertyName = metadataProperty.Key;
var property = efEntityType.GetProperty(propertyName);
if (property.ValueGenerated!=ValueGenerated.Never)
if (property.ValueGenerated != ValueGenerated.Never)
{
throw new ShardingCoreConfigException($"sharding table key:{propertyName} is not {nameof(ValueGenerated)}.{nameof(ValueGenerated.Never)}");
throw new ShardingCoreConfigException(
$"sharding table key:{propertyName} is not {nameof(ValueGenerated)}.{nameof(ValueGenerated.Never)}");
}
}
}
}
metadata.SetEntityModel(efEntityType);
if (!metadata.IsView)
{
if (string.IsNullOrWhiteSpace(metadata.LogicTableName))
{
throw new ShardingCoreInvalidOperationException(
$"init model error, cant get logic table name:[{metadata.LogicTableName}] from entity:[{efEntityType.ClrType}]");
}
if (!_logicTableCaches.TryGetValue(metadata.LogicTableName, out var metadatas))
{
metadatas = new List<EntityMetadata>();
_logicTableCaches.TryAdd(metadata.LogicTableName, metadatas);
}
if (metadatas.All(o => o.EntityType != efEntityType.ClrType))
{
metadatas.Add(metadata);
return true;
}
//添加完成后检查逻辑表对应的对象不可以存在两个以上的分片
if (metadatas.Count > 1 && metadatas.Any(o => o.IsShardingTable() || o.IsShardingDataSource()))
{
throw new ShardingCoreInvalidOperationException(
$"cant add logic table name caches for metadata:[{metadata.LogicTableName}-{efEntityType.ClrType}]");
}
metadata.SetEntityModel(efEntityType);
if (string.IsNullOrWhiteSpace(metadata.LogicTableName))
{
throw new ShardingCoreInvalidOperationException(
$"init model error, cant get logic table name:[{metadata.LogicTableName}] from entity:[{efEntityType.ClrType}],is view:[{metadata.IsView}]");
}
if (!_logicTableCaches.TryGetValue(metadata.LogicTableName, out var metadatas))
{
metadatas = new List<EntityMetadata>();
_logicTableCaches.TryAdd(metadata.LogicTableName, metadatas);
}
if (metadatas.All(o => o.EntityType != efEntityType.ClrType))
{
metadatas.Add(metadata);
return true;
}
//添加完成后检查逻辑表对应的对象不可以存在两个以上的分片
if (metadatas.Count > 1 && metadatas.Any(o => o.IsShardingTable() || o.IsShardingDataSource()))
{
throw new ShardingCoreInvalidOperationException(
$"cant add logic table name caches for metadata:[{metadata.LogicTableName}-{efEntityType.ClrType}]");
}
}

View File

@ -110,6 +110,11 @@ namespace ShardingCore.Core.EntityMetadatas
if (string.IsNullOrWhiteSpace(LogicTableName))
{
IsView = dbEntityType.GetEntityTypeIsView();
if (IsView)
{
LogicTableName = dbEntityType.GetEntityTypeViewName();
Schema = dbEntityType.GetEntityTypeViewSchema();
}
}
QueryFilterExpression =

View File

@ -16,7 +16,6 @@ using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Exceptions;
using ShardingCore.Extensions;
using ShardingCore.Extensions.InternalExtensions;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Utils;
@ -31,7 +30,6 @@ namespace ShardingCore.EFCores
*/
public class ShardingModelCustomizer : ModelCustomizer
{
public ShardingModelCustomizer(ModelCustomizerDependencies dependencies) : base(dependencies)
{
}
@ -39,55 +37,66 @@ namespace ShardingCore.EFCores
public override void Customize(ModelBuilder modelBuilder, DbContext context)
{
base.Customize(modelBuilder, context);
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.GetShardingRuntimeContext();
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
var isMultiEntityQuery = shardingTableDbContext.RouteTail.IsMultiEntityQuery();
if (!isMultiEntityQuery)
{
var singleQueryRouteTail = (ISingleQueryRouteTail) shardingTableDbContext.RouteTail;
var singleQueryRouteTail = (ISingleQueryRouteTail)shardingTableDbContext.RouteTail;
var tail = singleQueryRouteTail.GetTail();
//设置分表
var mutableEntityTypes = modelBuilder.Model.GetEntityTypes().Where(o => entityMetadataManager.IsShardingTable(o.ClrType)).ToArray();
var mutableEntityTypes = modelBuilder.Model.GetEntityTypes()
.Where(o => entityMetadataManager.IsShardingTable(o.ClrType)).ToArray();
foreach (var entityType in mutableEntityTypes)
{
MappingToTable(entityMetadataManager,entityType, modelBuilder, tail);
MappingToTable(entityMetadataManager, entityType, modelBuilder, tail);
}
}
else
{
var multiQueryRouteTail = (IMultiQueryRouteTail) shardingTableDbContext.RouteTail;
var multiQueryRouteTail = (IMultiQueryRouteTail)shardingTableDbContext.RouteTail;
var entityTypes = multiQueryRouteTail.GetEntityTypes();
var mutableEntityTypes = modelBuilder.Model.GetEntityTypes().Where(o => entityMetadataManager.IsShardingTable(o.ClrType) && entityTypes.Contains(o.ClrType)).ToArray();
var mutableEntityTypes = modelBuilder.Model.GetEntityTypes().Where(o =>
entityMetadataManager.IsShardingTable(o.ClrType) && entityTypes.Contains(o.ClrType)).ToArray();
foreach (var entityType in mutableEntityTypes)
{
var queryTail = multiQueryRouteTail.GetEntityTail(entityType.ClrType);
if (queryTail != null)
{
MappingToTable(entityMetadataManager,entityType, modelBuilder, queryTail);
MappingToTable(entityMetadataManager, entityType, modelBuilder, queryTail);
}
}
}
}
}
private void MappingToTable(IEntityMetadataManager entityMetadataManager,IMutableEntityType mutableEntityType, ModelBuilder modelBuilder, string tail)
private void MappingToTable(IEntityMetadataManager entityMetadataManager, IMutableEntityType mutableEntityType,
ModelBuilder modelBuilder, string tail)
{
var clrType = mutableEntityType.ClrType;
var entityMetadata = entityMetadataManager.TryGet(clrType);
if (entityMetadata == null)
throw new ShardingCoreInvalidOperationException($"not found entity type:[{clrType}]'s entity metadata");
if (entityMetadata.IsView)
{
throw new ShardingCoreInvalidOperationException(
$"entity type:[{clrType}]'s entity metadata is view cant remapping table name");
}
var shardingEntity = entityMetadata.EntityType;
var tableSeparator = entityMetadata.TableSeparator;
var entity = modelBuilder.Entity(shardingEntity);
var tableName = entityMetadata.LogicTableName;
if (string.IsNullOrWhiteSpace(tableName))
throw new ArgumentNullException($"{shardingEntity}: not found logic table name。");
entity.ToTable($"{tableName}{tableSeparator}{tail}",entityMetadata.Schema);
entity.ToTable($"{tableName}{tableSeparator}{tail}", entityMetadata.Schema);
}
}
}

View File

@ -44,7 +44,24 @@ namespace ShardingCore.Extensions.InternalExtensions
#if EFCORE2 ||EFCORE3
return false;
#endif
}
public static string GetEntityTypeViewName(this IEntityType entityType)
{
#if !EFCORE2&&!EFCORE3
return entityType.GetViewName();
#endif
#if EFCORE2 ||EFCORE3
return null;
#endif
}
public static string GetEntityTypeViewSchema(this IEntityType entityType)
{
#if !EFCORE2&&!EFCORE3
return entityType.GetViewSchema();
#endif
#if EFCORE2 ||EFCORE3
return null;
#endif
}
}
}