分efcore
This commit is contained in:
parent
436c902000
commit
28073bff13
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace ShardingCore.Core.DbContextTypeAwares;
|
namespace ShardingCore.Core.DbContextTypeAwares
|
||||||
|
{
|
||||||
public class DbContextTypeAware : IDbContextTypeAware
|
public class DbContextTypeAware : IDbContextTypeAware
|
||||||
{
|
{
|
||||||
private readonly Type _dbContextType;
|
private readonly Type _dbContextType;
|
||||||
|
@ -15,3 +15,4 @@ public class DbContextTypeAware:IDbContextTypeAware
|
||||||
return _dbContextType;
|
return _dbContextType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace ShardingCore.Core.DbContextTypeAwares;
|
namespace ShardingCore.Core.DbContextTypeAwares
|
||||||
|
{
|
||||||
public interface IDbContextTypeAware
|
public interface IDbContextTypeAware
|
||||||
{
|
{
|
||||||
Type GetContextType();
|
Type GetContextType();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
using ShardingCore.Sharding.Abstractions;
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
namespace ShardingCore.Core.RuntimeContexts;
|
namespace ShardingCore.Core.RuntimeContexts
|
||||||
|
{
|
||||||
public interface IShardingRuntimeContext<TDbContext> : IShardingRuntimeContext where TDbContext : IShardingDbContext
|
public interface IShardingRuntimeContext<TDbContext> : IShardingRuntimeContext where TDbContext : IShardingDbContext
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#if SHARDINGCORE2_6
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -33,21 +32,21 @@ namespace ShardingCore.Extensions
|
||||||
/// <param name="dbContext"></param>
|
/// <param name="dbContext"></param>
|
||||||
public static void RemoveDbContextRelationModelThatIsShardingTable(this DbContext dbContext)
|
public static void RemoveDbContextRelationModelThatIsShardingTable(this DbContext dbContext)
|
||||||
{
|
{
|
||||||
#if !EFCORE2 && !NETSTANDARD2_0 && !EFCORE3 && !NETSTANDARD2_1 && !EFCORE5 && !EFCORE6
|
#if !EFCORE2 && !EFCORE3 && !EFCORE5 && !EFCORE6 && !EFCORE7
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE6
|
#if EFCORE6 ||EFCORE7
|
||||||
|
|
||||||
var contextModel = dbContext.GetService<IDesignTimeModel>().Model; ;
|
var contextModel = dbContext.GetService<IDesignTimeModel>().Model;
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE2 || NETSTANDARD2_0 || EFCORE3 || EFCORE5 || NETSTANDARD2_1
|
#if EFCORE2 || EFCORE3 || EFCORE5
|
||||||
|
|
||||||
var contextModel = dbContext.Model as Model;
|
var contextModel = dbContext.Model as Model;
|
||||||
#endif
|
#endif
|
||||||
var shardingRuntimeContext = dbContext.GetShardingRuntimeContext();
|
var shardingRuntimeContext = dbContext.GetShardingRuntimeContext();
|
||||||
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
|
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
|
||||||
|
|
||||||
#if EFCORE6
|
#if EFCORE6 || EFCORE7
|
||||||
var entityTypes = contextModel.GetEntityTypes();
|
var entityTypes = contextModel.GetEntityTypes();
|
||||||
foreach (var entityType in entityTypes)
|
foreach (var entityType in entityTypes)
|
||||||
{
|
{
|
||||||
|
@ -64,7 +63,7 @@ namespace ShardingCore.Extensions
|
||||||
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE5 || NETSTANDARD2_1
|
#if EFCORE5
|
||||||
var entityTypes = contextModel.GetEntityTypes();
|
var entityTypes = contextModel.GetEntityTypes();
|
||||||
foreach (var entityType in entityTypes)
|
foreach (var entityType in entityTypes)
|
||||||
{
|
{
|
||||||
|
@ -81,7 +80,7 @@ namespace ShardingCore.Extensions
|
||||||
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE2 || NETSTANDARD2_0 || EFCORE3
|
#if EFCORE2 || EFCORE3
|
||||||
var entityTypes =
|
var entityTypes =
|
||||||
contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>;
|
contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>;
|
||||||
foreach (var entityType in entityTypes)
|
foreach (var entityType in entityTypes)
|
||||||
|
@ -133,14 +132,14 @@ namespace ShardingCore.Extensions
|
||||||
/// <param name="dbContext"></param>
|
/// <param name="dbContext"></param>
|
||||||
public static void RemoveDbContextAllRelationModelWithoutShardingDataSourceOnly(this DbContext dbContext)
|
public static void RemoveDbContextAllRelationModelWithoutShardingDataSourceOnly(this DbContext dbContext)
|
||||||
{
|
{
|
||||||
#if !EFCORE2 && !NETSTANDARD2_0 && !EFCORE3 && !NETSTANDARD2_1 && !EFCORE5 && !EFCORE6
|
#if !EFCORE2&& !EFCORE3 && !EFCORE5 && !EFCORE6 && !EFCORE7
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE6
|
#if EFCORE6 || EFCORE7
|
||||||
|
|
||||||
var contextModel = dbContext.GetService<IDesignTimeModel>().Model; ;
|
var contextModel = dbContext.GetService<IDesignTimeModel>().Model; ;
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE2 || EFCORE3 || NETSTANDARD2_0 || EFCORE5 || NETSTANDARD2_1
|
#if EFCORE2 || EFCORE3 || EFCORE5
|
||||||
|
|
||||||
var contextModel = dbContext.Model as Model;
|
var contextModel = dbContext.Model as Model;
|
||||||
#endif
|
#endif
|
||||||
|
@ -164,7 +163,7 @@ namespace ShardingCore.Extensions
|
||||||
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE5 || NETSTANDARD2_1
|
#if EFCORE5
|
||||||
var entityTypes = contextModel.GetEntityTypes();
|
var entityTypes = contextModel.GetEntityTypes();
|
||||||
foreach (var entityType in entityTypes)
|
foreach (var entityType in entityTypes)
|
||||||
{
|
{
|
||||||
|
@ -181,7 +180,7 @@ namespace ShardingCore.Extensions
|
||||||
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE2 || NETSTANDARD2_0 || EFCORE3
|
#if EFCORE2 || EFCORE3
|
||||||
|
|
||||||
var entityTypes =
|
var entityTypes =
|
||||||
contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>;
|
contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>;
|
||||||
|
@ -205,14 +204,14 @@ namespace ShardingCore.Extensions
|
||||||
/// <param name="dbContext"></param>
|
/// <param name="dbContext"></param>
|
||||||
public static void RemoveDbContextAllRelationModel(this DbContext dbContext)
|
public static void RemoveDbContextAllRelationModel(this DbContext dbContext)
|
||||||
{
|
{
|
||||||
#if !EFCORE2 && !NETSTANDARD2_0 && !EFCORE3 && !NETSTANDARD2_1 && !EFCORE5 && !EFCORE6
|
#if !EFCORE2 && !EFCORE3 && !EFCORE5 && !EFCORE6&& !EFCORE7
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE6
|
#if EFCORE6|| EFCORE7
|
||||||
|
|
||||||
var contextModel = dbContext.GetService<IDesignTimeModel>().Model; ;
|
var contextModel = dbContext.GetService<IDesignTimeModel>().Model; ;
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE2 || EFCORE3 || NETSTANDARD2_0 || EFCORE5 || NETSTANDARD2_1
|
#if EFCORE2 || EFCORE3 || EFCORE5
|
||||||
|
|
||||||
var contextModel = dbContext.Model as Model;
|
var contextModel = dbContext.Model as Model;
|
||||||
#endif
|
#endif
|
||||||
|
@ -221,11 +220,11 @@ namespace ShardingCore.Extensions
|
||||||
var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel;
|
var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel;
|
||||||
contextModelRelationalModel.Tables.Clear();
|
contextModelRelationalModel.Tables.Clear();
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE5 || NETSTANDARD2_1
|
#if EFCORE5
|
||||||
var contextModelRelationalModel = contextModel.RelationalModel as RelationalModel;
|
var contextModelRelationalModel = contextModel.RelationalModel as RelationalModel;
|
||||||
contextModelRelationalModel.Tables.Clear();
|
contextModelRelationalModel.Tables.Clear();
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE2 || EFCORE3 || NETSTANDARD2_0
|
#if EFCORE2 || EFCORE3
|
||||||
var entityTypes =
|
var entityTypes =
|
||||||
contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>;
|
contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>;
|
||||||
entityTypes.Clear();
|
entityTypes.Clear();
|
||||||
|
@ -240,14 +239,14 @@ namespace ShardingCore.Extensions
|
||||||
public static void RemoveDbContextRelationModelSaveOnlyThatIsNamedType(this DbContext dbContext,
|
public static void RemoveDbContextRelationModelSaveOnlyThatIsNamedType(this DbContext dbContext,
|
||||||
Type shardingType)
|
Type shardingType)
|
||||||
{
|
{
|
||||||
#if !EFCORE2 && !NETSTANDARD2_0 && !EFCORE3 && !NETSTANDARD2_1 && !EFCORE5 && !EFCORE6
|
#if !EFCORE2 && !EFCORE3 && !EFCORE5 && !EFCORE6&& !EFCORE7
|
||||||
1
|
1
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE2 || NETSTANDARD2_0 || EFCORE3 ||EFCORE5 || NETSTANDARD2_1
|
#if EFCORE2 || EFCORE3 || EFCORE5
|
||||||
|
|
||||||
var contextModel = dbContext.Model as Model;
|
var contextModel = dbContext.Model as Model;
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE6
|
#if EFCORE6 || EFCORE7
|
||||||
var contextModel = dbContext.GetService<IDesignTimeModel>().Model;
|
var contextModel = dbContext.GetService<IDesignTimeModel>().Model;
|
||||||
var entityTypes = contextModel.GetEntityTypes();
|
var entityTypes = contextModel.GetEntityTypes();
|
||||||
foreach (var entityType in entityTypes)
|
foreach (var entityType in entityTypes)
|
||||||
|
@ -268,7 +267,7 @@ namespace ShardingCore.Extensions
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if EFCORE5 || NETSTANDARD2_1
|
#if EFCORE5
|
||||||
var contextModelRelationalModel = contextModel.RelationalModel as RelationalModel;
|
var contextModelRelationalModel = contextModel.RelationalModel as RelationalModel;
|
||||||
|
|
||||||
var entityTypes = contextModel.GetEntityTypes();
|
var entityTypes = contextModel.GetEntityTypes();
|
||||||
|
@ -287,7 +286,7 @@ namespace ShardingCore.Extensions
|
||||||
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE2 || NETSTANDARD2_0 || EFCORE3
|
#if EFCORE2 || EFCORE3
|
||||||
var entityTypes =
|
var entityTypes =
|
||||||
contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>;
|
contextModel.GetFieldValue("_entityTypes") as SortedDictionary<string, EntityType>;
|
||||||
|
|
||||||
|
@ -318,10 +317,10 @@ namespace ShardingCore.Extensions
|
||||||
/// <param name="dbContext"></param>
|
/// <param name="dbContext"></param>
|
||||||
public static void RemoveModelCache(this DbContext dbContext)
|
public static void RemoveModelCache(this DbContext dbContext)
|
||||||
{
|
{
|
||||||
#if !EFCORE2 && !NETSTANDARD2_0 && !EFCORE3 && !NETSTANDARD2_1 && !EFCORE5 && !EFCORE6
|
#if !EFCORE2 && !EFCORE3 && !EFCORE5 && !EFCORE6 && !EFCORE7
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE6
|
#if EFCORE6 || EFCORE7
|
||||||
var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||||
var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
||||||
object key1 = modelCacheKeyFactory.Create(dbContext,true);
|
object key1 = modelCacheKeyFactory.Create(dbContext,true);
|
||||||
|
@ -329,13 +328,13 @@ namespace ShardingCore.Extensions
|
||||||
object key2 = modelCacheKeyFactory.Create(dbContext,false);
|
object key2 = modelCacheKeyFactory.Create(dbContext,false);
|
||||||
shardingModelSource.Remove(key2);
|
shardingModelSource.Remove(key2);
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE5 || NETSTANDARD2_1
|
#if EFCORE5
|
||||||
var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||||
var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
||||||
object key1 = modelCacheKeyFactory.Create(dbContext);
|
object key1 = modelCacheKeyFactory.Create(dbContext);
|
||||||
shardingModelSource.Remove(key1);
|
shardingModelSource.Remove(key1);
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE3 || NETSTANDARD2_0
|
#if EFCORE3
|
||||||
|
|
||||||
var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
||||||
var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
||||||
|
@ -415,4 +414,3 @@ namespace ShardingCore.Extensions
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
|
@ -1,203 +0,0 @@
|
||||||
#if EFCORE7
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Internal;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
|
||||||
using ShardingCore.Core.RuntimeContexts;
|
|
||||||
using ShardingCore.EFCores;
|
|
||||||
using ShardingCore.Exceptions;
|
|
||||||
|
|
||||||
namespace ShardingCore.Extensions
|
|
||||||
{
|
|
||||||
[ExcludeFromCodeCoverage]
|
|
||||||
public static class DbContextExtension
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 移除所有的分表关系的模型
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dbContext"></param>
|
|
||||||
public static void RemoveDbContextRelationModelThatIsShardingTable(this DbContext dbContext)
|
|
||||||
{
|
|
||||||
|
|
||||||
var contextModel = dbContext.GetService<IDesignTimeModel>().Model; ;
|
|
||||||
var shardingRuntimeContext = dbContext.GetShardingRuntimeContext();
|
|
||||||
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
|
|
||||||
|
|
||||||
var entityTypes = contextModel.GetEntityTypes();
|
|
||||||
foreach (var entityType in entityTypes)
|
|
||||||
{
|
|
||||||
if (entityType.GetFieldValue("_data") is List<object> _data)
|
|
||||||
{
|
|
||||||
_data.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel;
|
|
||||||
var valueTuples =
|
|
||||||
contextModelRelationalModel.Tables.Where(o =>o.Value.EntityTypeMappings.Any(m => entityMetadataManager.IsShardingTable(m.EntityType.ClrType))).Select(o => o.Key).ToList();
|
|
||||||
for (int i = 0; i < valueTuples.Count; i++)
|
|
||||||
{
|
|
||||||
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 移除所有除了仅分库的
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dbContext"></param>
|
|
||||||
public static void RemoveDbContextAllRelationModelWithoutShardingDataSourceOnly(this DbContext dbContext)
|
|
||||||
{
|
|
||||||
|
|
||||||
var contextModel = dbContext.GetService<IDesignTimeModel>().Model; ;
|
|
||||||
|
|
||||||
var shardingRuntimeContext = dbContext.GetShardingRuntimeContext();
|
|
||||||
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
|
|
||||||
|
|
||||||
var entityTypes = contextModel.GetEntityTypes();
|
|
||||||
foreach (var entityType in entityTypes)
|
|
||||||
{
|
|
||||||
if (entityType.GetFieldValue("_data") is List<object> _data)
|
|
||||||
{
|
|
||||||
_data.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel;
|
|
||||||
var valueTuples =
|
|
||||||
contextModelRelationalModel.Tables.Where(o => o.Value.EntityTypeMappings.Any(m => !entityMetadataManager.IsShardingDataSource(m.EntityType.ClrType) ||entityMetadataManager.TryGet(m.EntityType.ClrType)==null)).Select(o => o.Key).ToList();
|
|
||||||
for (int i = 0; i < valueTuples.Count; i++)
|
|
||||||
{
|
|
||||||
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 移除所有的表
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dbContext"></param>
|
|
||||||
public static void RemoveDbContextAllRelationModel(this DbContext dbContext)
|
|
||||||
{
|
|
||||||
|
|
||||||
var contextModel = dbContext.GetService<IDesignTimeModel>().Model; ;
|
|
||||||
|
|
||||||
var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel;
|
|
||||||
contextModelRelationalModel.Tables.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 移除所有的除了我指定的那个类型
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dbContext"></param>
|
|
||||||
/// <param name="shardingType"></param>
|
|
||||||
public static void RemoveDbContextRelationModelSaveOnlyThatIsNamedType(this DbContext dbContext,
|
|
||||||
Type shardingType)
|
|
||||||
{
|
|
||||||
var contextModel = dbContext.GetService<IDesignTimeModel>().Model;
|
|
||||||
var entityTypes = contextModel.GetEntityTypes();
|
|
||||||
foreach (var entityType in entityTypes)
|
|
||||||
{
|
|
||||||
if (entityType.GetFieldValue("_data") is List<object> _data)
|
|
||||||
{
|
|
||||||
_data.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var contextModelRelationalModel = contextModel.GetRelationalModel() as RelationalModel;
|
|
||||||
var valueTuples =
|
|
||||||
contextModelRelationalModel.Tables
|
|
||||||
.Where(o => o.Value.EntityTypeMappings.All(m => m.EntityType.ClrType != shardingType))
|
|
||||||
.Select(o => o.Key).ToList();
|
|
||||||
for (int i = 0; i < valueTuples.Count; i++)
|
|
||||||
{
|
|
||||||
contextModelRelationalModel.Tables.Remove(valueTuples[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RemoveDbContextRelationModelSaveOnlyThatIsNamedType<T>(this DbContext dbContext)
|
|
||||||
where T:class
|
|
||||||
{
|
|
||||||
RemoveDbContextRelationModelSaveOnlyThatIsNamedType(dbContext, typeof(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 移除模型缓存
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dbContext"></param>
|
|
||||||
public static void RemoveModelCache(this DbContext dbContext)
|
|
||||||
{
|
|
||||||
var shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
|
||||||
var modelCacheKeyFactory = shardingModelSource.GetModelCacheKeyFactory();
|
|
||||||
object key1 = modelCacheKeyFactory.Create(dbContext,true);
|
|
||||||
shardingModelSource.Remove(key1);
|
|
||||||
object key2 = modelCacheKeyFactory.Create(dbContext,false);
|
|
||||||
shardingModelSource.Remove(key2);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取模型创建的锁
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dbContext"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static object GetModelCacheSyncObject(this DbContext dbContext)
|
|
||||||
{
|
|
||||||
IShardingModelSource shardingModelSource = dbContext.GetService<IModelSource>() as IShardingModelSource;
|
|
||||||
return shardingModelSource.GetSyncObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static IEnumerable<object> GetPrimaryKeyValues<TEntity>(TEntity entity,IKey primaryKey) where TEntity : class
|
|
||||||
{
|
|
||||||
return primaryKey.Properties.Select(o =>entity.GetPropertyValue(o.Name));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TEntity GetAttachedEntity<TEntity>(this DbContext context, TEntity entity) where TEntity:class
|
|
||||||
{
|
|
||||||
if (entity == null) { throw new ArgumentNullException(nameof(entity)); }
|
|
||||||
var entityPrimaryKey = context.Model.FindRuntimeEntityType(entity.GetType()).FindPrimaryKey();
|
|
||||||
if (entityPrimaryKey == null)
|
|
||||||
{
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
var primaryKeyValue = GetPrimaryKeyValues(entity, entityPrimaryKey).ToArray();
|
|
||||||
if (primaryKeyValue.IsEmpty())
|
|
||||||
return null;
|
|
||||||
var dbContextDependencies = (IDbContextDependencies)typeof(DbContext).GetTypePropertyValue(context, "DbContextDependencies");
|
|
||||||
var stateManager = dbContextDependencies.StateManager;
|
|
||||||
|
|
||||||
//var entityIKey = ShardingKeyUtil.GetEntityIKey(entity);
|
|
||||||
var internalEntityEntry = stateManager.TryGetEntry(entityPrimaryKey, primaryKeyValue);
|
|
||||||
|
|
||||||
if (internalEntityEntry == null)
|
|
||||||
return null;
|
|
||||||
return (TEntity)internalEntityEntry.Entity;
|
|
||||||
//sp.Restart();
|
|
||||||
|
|
||||||
//var entityEntries = context.ChangeTracker.Entries<TEntity>();
|
|
||||||
//sp.Stop();
|
|
||||||
//Console.WriteLine($"ChangeTracker.Entries:{sp.ElapsedMilliseconds}毫秒");
|
|
||||||
//sp.Restart();
|
|
||||||
//var entry = entityEntries.Where(e => e.State != EntityState.Detached && primaryKeyValue.SequenceEqual(ShardingKeyUtil.GetPrimaryKeyValues(e.Entity))).FirstOrDefault();
|
|
||||||
//sp.Stop();
|
|
||||||
//Console.WriteLine($"ChangeTracker.FirstOrDefault:{sp.ElapsedMilliseconds}毫秒");
|
|
||||||
//return entry?.Entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IShardingRuntimeContext GetShardingRuntimeContext(this DbContext dbContext)
|
|
||||||
{
|
|
||||||
var shardingRuntimeContext = dbContext.GetService<IShardingRuntimeContext>();
|
|
||||||
|
|
||||||
if (shardingRuntimeContext == null)
|
|
||||||
{
|
|
||||||
throw new ShardingCoreInvalidOperationException($"cant resolve:[{typeof(IShardingRuntimeContext)}],dbcontext:[{dbContext}]");
|
|
||||||
}
|
|
||||||
|
|
||||||
return shardingRuntimeContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -46,7 +46,7 @@ namespace ShardingCore.Sharding.Enumerators.StreamMergeAsync
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE3 || NETSTANDARD2_0 || EFCORE5 || NETSTANDARD2_1
|
#if EFCORE3 || EFCORE5
|
||||||
public ValueTask DisposeAsync()
|
public ValueTask DisposeAsync()
|
||||||
{
|
{
|
||||||
return new ValueTask();
|
return new ValueTask();
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#if SHARDINGCORE2_6
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
@ -134,7 +133,7 @@ namespace ShardingCore.Core.Internal.Visitors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if EFCORE2 || EFCORE3 || NETSTANDARD2_0
|
#if EFCORE2 || EFCORE3
|
||||||
internal class DbContextReplaceQueryableVisitor : DbContextInnerMemberReferenceReplaceQueryableVisitor
|
internal class DbContextReplaceQueryableVisitor : DbContextInnerMemberReferenceReplaceQueryableVisitor
|
||||||
{
|
{
|
||||||
private readonly DbContext _dbContext;
|
private readonly DbContext _dbContext;
|
||||||
|
@ -174,7 +173,7 @@ namespace ShardingCore.Core.Internal.Visitors
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if EFCORE5 || NETSTANDARD2_1 || EFCORE6
|
#if EFCORE5 || EFCORE6 ||EFCORE7
|
||||||
internal class DbContextReplaceQueryableVisitor : DbContextInnerMemberReferenceReplaceQueryableVisitor
|
internal class DbContextReplaceQueryableVisitor : DbContextInnerMemberReferenceReplaceQueryableVisitor
|
||||||
{
|
{
|
||||||
private readonly DbContext _dbContext;
|
private readonly DbContext _dbContext;
|
||||||
|
@ -192,9 +191,17 @@ namespace ShardingCore.Core.Internal.Visitors
|
||||||
var dbContextDependencies =
|
var dbContextDependencies =
|
||||||
typeof(DbContext).GetTypePropertyValue(_dbContext, "DbContextDependencies") as
|
typeof(DbContext).GetTypePropertyValue(_dbContext, "DbContextDependencies") as
|
||||||
IDbContextDependencies;
|
IDbContextDependencies;
|
||||||
|
#if !EFCORE7
|
||||||
var targetIQ =
|
var targetIQ =
|
||||||
(IQueryable)((IDbSetCache)_dbContext).GetOrAddSet(dbContextDependencies.SetSource,
|
(IQueryable)((IDbSetCache)_dbContext).GetOrAddSet(dbContextDependencies.SetSource,
|
||||||
queryRootExpression.EntityType.ClrType);
|
queryRootExpression.EntityType.ClrType);
|
||||||
|
#endif
|
||||||
|
#if EFCORE7
|
||||||
|
|
||||||
|
var targetIQ =
|
||||||
|
(IQueryable)((IDbSetCache)_dbContext).GetOrAddSet(dbContextDependencies.SetSource,
|
||||||
|
queryRootExpression.ElementType);
|
||||||
|
#endif
|
||||||
|
|
||||||
var newQueryable = targetIQ.Provider.CreateQuery(targetIQ.Expression);
|
var newQueryable = targetIQ.Provider.CreateQuery(targetIQ.Expression);
|
||||||
if (Source == null)
|
if (Source == null)
|
||||||
|
@ -202,10 +209,16 @@ namespace ShardingCore.Core.Internal.Visitors
|
||||||
RootIsVisit = true;
|
RootIsVisit = true;
|
||||||
if (queryRootExpression is FromSqlQueryRootExpression fromSqlQueryRootExpression)
|
if (queryRootExpression is FromSqlQueryRootExpression fromSqlQueryRootExpression)
|
||||||
{
|
{
|
||||||
|
#if !EFCORE7
|
||||||
var sqlQueryRootExpression = new FromSqlQueryRootExpression(newQueryable.Provider as IAsyncQueryProvider,
|
var sqlQueryRootExpression = new FromSqlQueryRootExpression(newQueryable.Provider as IAsyncQueryProvider,
|
||||||
queryRootExpression.EntityType, fromSqlQueryRootExpression.Sql,
|
queryRootExpression.EntityType, fromSqlQueryRootExpression.Sql,
|
||||||
fromSqlQueryRootExpression.Argument);
|
fromSqlQueryRootExpression.Argument);
|
||||||
|
#endif
|
||||||
|
#if EFCORE7
|
||||||
|
var sqlQueryRootExpression = new FromSqlQueryRootExpression(newQueryable.Provider as IAsyncQueryProvider,
|
||||||
|
fromSqlQueryRootExpression.EntityType, fromSqlQueryRootExpression.Sql,
|
||||||
|
fromSqlQueryRootExpression.Argument);
|
||||||
|
#endif
|
||||||
return base.VisitExtension(sqlQueryRootExpression);
|
return base.VisitExtension(sqlQueryRootExpression);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -239,4 +252,3 @@ namespace ShardingCore.Core.Internal.Visitors
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,201 +0,0 @@
|
||||||
#if EFCORE7
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Reflection;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Internal;
|
|
||||||
using Microsoft.EntityFrameworkCore.Query;
|
|
||||||
using Microsoft.EntityFrameworkCore.Query.Internal;
|
|
||||||
using ShardingCore.Core.Internal.Visitors;
|
|
||||||
using ShardingCore.Exceptions;
|
|
||||||
using ShardingCore.Extensions;
|
|
||||||
|
|
||||||
namespace ShardingCore.Core.Internal.Visitors
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Wednesday, 13 January 2021 16:32:27
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
|
|
||||||
internal class DbContextInnerMemberReferenceReplaceQueryableVisitor : ShardingExpressionVisitor
|
|
||||||
{
|
|
||||||
private readonly DbContext _dbContext;
|
|
||||||
protected bool RootIsVisit = false;
|
|
||||||
|
|
||||||
public DbContextInnerMemberReferenceReplaceQueryableVisitor(DbContext dbContext)
|
|
||||||
{
|
|
||||||
_dbContext = dbContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public override Expression Visit(Expression node)
|
|
||||||
// {
|
|
||||||
// Console.WriteLine("1");
|
|
||||||
// return base.Visit(node);
|
|
||||||
// }
|
|
||||||
|
|
||||||
protected override Expression VisitMember
|
|
||||||
(MemberExpression memberExpression)
|
|
||||||
{
|
|
||||||
// Recurse down to see if we can simplify...
|
|
||||||
if (memberExpression.IsMemberQueryable()) //2x,3x 路由 单元测试 分表和不分表
|
|
||||||
{
|
|
||||||
var expressionValue = GetExpressionValue(memberExpression);
|
|
||||||
if (expressionValue is IQueryable queryable)
|
|
||||||
{
|
|
||||||
return ReplaceMemberExpression(queryable);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expressionValue is DbContext dbContext)
|
|
||||||
{
|
|
||||||
return ReplaceMemberExpression(dbContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.VisitMember(memberExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MemberExpression ReplaceMemberExpression(IQueryable queryable)
|
|
||||||
{
|
|
||||||
var dbContextReplaceQueryableVisitor = new DbContextReplaceQueryableVisitor(_dbContext);
|
|
||||||
var newExpression = dbContextReplaceQueryableVisitor.Visit(queryable.Expression);
|
|
||||||
var newQueryable = dbContextReplaceQueryableVisitor.Source.Provider.CreateQuery(newExpression);
|
|
||||||
var tempVariableGenericType = typeof(TempVariable<>).GetGenericType0(queryable.ElementType);
|
|
||||||
var tempVariable = Activator.CreateInstance(tempVariableGenericType, newQueryable);
|
|
||||||
MemberExpression queryableMemberReplaceExpression =
|
|
||||||
Expression.Property(ConstantExpression.Constant(tempVariable), nameof(TempVariable<object>.Queryable));
|
|
||||||
return queryableMemberReplaceExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MemberExpression ReplaceMemberExpression(DbContext dbContext)
|
|
||||||
{
|
|
||||||
var tempVariableGenericType = typeof(TempDbVariable<>).GetGenericType0(dbContext.GetType());
|
|
||||||
var tempVariable = Activator.CreateInstance(tempVariableGenericType, _dbContext);
|
|
||||||
MemberExpression dbContextMemberReplaceExpression =
|
|
||||||
Expression.Property(ConstantExpression.Constant(tempVariable),
|
|
||||||
nameof(TempDbVariable<object>.DbContext));
|
|
||||||
return dbContextMemberReplaceExpression;
|
|
||||||
}
|
|
||||||
protected override Expression VisitMethodCall(MethodCallExpression node)
|
|
||||||
{
|
|
||||||
if (RootIsVisit&&node.Method.ReturnType.IsMethodReturnTypeQueryableType()&&node.Method.ReturnType.IsGenericType)
|
|
||||||
{
|
|
||||||
var notRoot = node.Arguments.IsEmpty();
|
|
||||||
|
|
||||||
if (notRoot)
|
|
||||||
{
|
|
||||||
var entityType = node.Method.ReturnType.GenericTypeArguments[0];
|
|
||||||
|
|
||||||
var whereCallExpression = ReplaceMethodCallExpression(node, entityType);
|
|
||||||
return whereCallExpression;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.VisitMethodCall(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MethodCallExpression ReplaceMethodCallExpression(MethodCallExpression methodCallExpression,
|
|
||||||
Type entityType)
|
|
||||||
{
|
|
||||||
MethodCallExpression whereCallExpression = Expression.Call(
|
|
||||||
typeof(IShardingQueryableExtension),
|
|
||||||
nameof(IShardingQueryableExtension.ReplaceDbContextQueryableWithType),
|
|
||||||
new Type[] { entityType },
|
|
||||||
methodCallExpression, Expression.Constant(_dbContext)
|
|
||||||
);
|
|
||||||
return whereCallExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed class TempVariable<T1>
|
|
||||||
{
|
|
||||||
public IQueryable<T1> Queryable { get; }
|
|
||||||
|
|
||||||
public TempVariable(IQueryable<T1> queryable)
|
|
||||||
{
|
|
||||||
Queryable = queryable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQueryable<T1> GetQueryable()
|
|
||||||
{
|
|
||||||
return Queryable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed class TempDbVariable<T1>
|
|
||||||
{
|
|
||||||
public T1 DbContext { get; }
|
|
||||||
|
|
||||||
public TempDbVariable(T1 dbContext)
|
|
||||||
{
|
|
||||||
DbContext = dbContext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal class DbContextReplaceQueryableVisitor : DbContextInnerMemberReferenceReplaceQueryableVisitor
|
|
||||||
{
|
|
||||||
private readonly DbContext _dbContext;
|
|
||||||
public IQueryable Source;
|
|
||||||
|
|
||||||
public DbContextReplaceQueryableVisitor(DbContext dbContext) : base(dbContext)
|
|
||||||
{
|
|
||||||
_dbContext = dbContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Expression VisitExtension(Expression node)
|
|
||||||
{
|
|
||||||
if (node is QueryRootExpression queryRootExpression)
|
|
||||||
{
|
|
||||||
var dbContextDependencies =
|
|
||||||
typeof(DbContext).GetTypePropertyValue(_dbContext, "DbContextDependencies") as
|
|
||||||
IDbContextDependencies;
|
|
||||||
var targetIQ =
|
|
||||||
(IQueryable)((IDbSetCache)_dbContext).GetOrAddSet(dbContextDependencies.SetSource,
|
|
||||||
queryRootExpression.ElementType);
|
|
||||||
|
|
||||||
var newQueryable = targetIQ.Provider.CreateQuery(targetIQ.Expression);
|
|
||||||
if (Source == null)
|
|
||||||
Source = newQueryable;
|
|
||||||
RootIsVisit = true;
|
|
||||||
|
|
||||||
if (queryRootExpression is FromSqlQueryRootExpression fromSqlQueryRootExpression)
|
|
||||||
{
|
|
||||||
var sqlQueryRootExpression = new FromSqlQueryRootExpression(newQueryable.Provider as IAsyncQueryProvider,
|
|
||||||
fromSqlQueryRootExpression.EntityType, fromSqlQueryRootExpression.Sql,
|
|
||||||
fromSqlQueryRootExpression.Argument);
|
|
||||||
|
|
||||||
return base.VisitExtension(sqlQueryRootExpression);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//如何替换ef5的set
|
|
||||||
var replaceQueryRoot = new ReplaceSingleQueryRootExpressionVisitor();
|
|
||||||
replaceQueryRoot.Visit(newQueryable.Expression);
|
|
||||||
return base.VisitExtension(replaceQueryRoot.QueryRootExpression);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.VisitExtension(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal sealed class ReplaceSingleQueryRootExpressionVisitor : ExpressionVisitor
|
|
||||||
{
|
|
||||||
public QueryRootExpression QueryRootExpression { get; set; }
|
|
||||||
|
|
||||||
protected override Expression VisitExtension(Expression node)
|
|
||||||
{
|
|
||||||
if (node is QueryRootExpression queryRootExpression)
|
|
||||||
{
|
|
||||||
if (QueryRootExpression != null)
|
|
||||||
throw new ShardingCoreException("replace query root more than one query root");
|
|
||||||
QueryRootExpression = queryRootExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.VisitExtension(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,6 +1,6 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net6;net7;</TargetFrameworks>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Version>$(EFCORE7)</Version>
|
<Version>$(EFCORE7)</Version>
|
||||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||||
<DefineConstants>TRACE;DEBUG;EFCORE7;</DefineConstants>
|
<DefineConstants>TRACE;DEBUG;EFCORE7;</DefineConstants>
|
||||||
|
|
Loading…
Reference in New Issue