diff --git a/nuget-publish.bat b/nuget-publish.bat
index 837a69af..263fe3b9 100644
--- a/nuget-publish.bat
+++ b/nuget-publish.bat
@@ -1,8 +1,8 @@
:start
::定义版本
-set EFCORE2=2.3.1.10
-set EFCORE3=3.3.1.10
-set EFCORE5=5.3.1.10
+set EFCORE2=2.3.1.11
+set EFCORE3=3.3.1.11
+set EFCORE5=5.3.1.11
::删除所有bin与obj下的文件
@echo off
diff --git a/samples/Samples.AbpSharding/AbstractShardingAbpDbContext.cs b/samples/Samples.AbpSharding/AbstractShardingAbpDbContext.cs
index 7d946383..e62fb677 100644
--- a/samples/Samples.AbpSharding/AbstractShardingAbpDbContext.cs
+++ b/samples/Samples.AbpSharding/AbstractShardingAbpDbContext.cs
@@ -60,7 +60,7 @@ namespace Samples.AbpSharding
//public void ShardingUpgrade()
//{
- // //isExecutor = true;
+ // //IsExecutor = true;
//}
public DbContext GetDbContext(string dataSourceName, bool parallelQuery, IRouteTail routeTail)
diff --git a/src/ShardingCore/Core/VirtualDatabase/ShardingEntityConfig.cs b/src/ShardingCore/Core/VirtualDatabase/ShardingEntityConfig.cs
index 9b85a0d1..3baec6f7 100644
--- a/src/ShardingCore/Core/VirtualDatabase/ShardingEntityConfig.cs
+++ b/src/ShardingCore/Core/VirtualDatabase/ShardingEntityConfig.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Reflection;
using System.Text;
namespace ShardingCore.Core.VirtualDatabase
@@ -29,6 +30,11 @@ namespace ShardingCore.Core.VirtualDatabase
/// 分库字段
///
public string ShardingDataSourceField { get; set; }
+ ///
+ /// 主键名称
+ ///
+ public string SinglePrimaryKeyFieldName { get; set; }
+
///
/// 启动时是否建表 auto create data source when start app
diff --git a/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/IVirtualDataSource.cs b/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/IVirtualDataSource.cs
index 0e5513c1..b9765b80 100644
--- a/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/IVirtualDataSource.cs
+++ b/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/IVirtualDataSource.cs
@@ -15,11 +15,8 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
* @Date: Friday, 05 February 2021 13:01:39
* @Email: 326308290@qq.com
*/
- ///
- /// 虚拟数据源 连接所有的实际数据源
- ///
- public interface IVirtualDataSource
- where TShardingDbContext : DbContext, IShardingDbContext
+
+ public interface IVirtualDataSource
{
string DefaultDataSourceName { get; }
///
@@ -55,4 +52,11 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
bool AddVirtualDataSourceRoute(IVirtualDataSourceRoute virtualDataSourceRoute);
bool IsDefault(string dataSourceName);
}
+ ///
+ /// 虚拟数据源 连接所有的实际数据源
+ ///
+ public interface IVirtualDataSource : IVirtualDataSource
+ where TShardingDbContext : DbContext, IShardingDbContext
+ {
+ }
}
\ No newline at end of file
diff --git a/src/ShardingCore/EFCores/ShardingInternalDbSet.cs b/src/ShardingCore/EFCores/ShardingInternalDbSet.cs
index e846a281..7fb192c6 100644
--- a/src/ShardingCore/EFCores/ShardingInternalDbSet.cs
+++ b/src/ShardingCore/EFCores/ShardingInternalDbSet.cs
@@ -8,6 +8,12 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
+using ShardingCore.Core.VirtualDatabase.VirtualTables;
+using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails;
+using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
+using ShardingCore.Extensions;
+using ShardingCore.Utils;
namespace ShardingCore.EFCores
{
@@ -37,6 +43,40 @@ namespace ShardingCore.EFCores
_context = (IShardingDbContext)context;
}
#endif
+ private IVirtualDataSource _virtualDataSource;
+
+ protected IVirtualDataSource VirtualDataSource
+ {
+ get
+ {
+ if (null == _virtualDataSource)
+ {
+ _virtualDataSource =
+ (IVirtualDataSource) ShardingContainer.GetService(
+ typeof(IVirtualDataSource<>).GetGenericType0(_context.GetType()));
+ }
+
+ return _virtualDataSource;
+ }
+ }
+
+ private IVirtualTableManager _virtualTableManager;
+
+ protected IVirtualTableManager VirtualTableManager
+ {
+ get
+ {
+ if (null == _virtualTableManager)
+ {
+ _virtualTableManager =
+ (IVirtualTableManager) ShardingContainer.GetService(
+ typeof(IVirtualTableManager<>).GetGenericType0(_context.GetType()));
+ }
+
+ return _virtualTableManager;
+ }
+ }
+
///
/// 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
@@ -366,6 +406,89 @@ namespace ShardingCore.EFCores
}
}
+ public override TEntity Find(params object[] keyValues)
+ {
+ var primaryKeyFindDbContext = GetDbContextByKeyValue(keyValues);
+ if (primaryKeyFindDbContext != null)
+ {
+ return primaryKeyFindDbContext.Set().Find(keyValues);
+ }
+ return base.Find(keyValues);
+ }
+
+#if !EFCORE2
+ public override ValueTask FindAsync(params object[] keyValues)
+ {
+ var primaryKeyFindDbContext = GetDbContextByKeyValue(keyValues);
+ if (primaryKeyFindDbContext != null)
+ {
+ return primaryKeyFindDbContext.Set().FindAsync(keyValues);
+ }
+ return base.FindAsync(keyValues);
+ }
+
+ public override ValueTask FindAsync(object[] keyValues, CancellationToken cancellationToken)
+ {
+ var primaryKeyFindDbContext = GetDbContextByKeyValue(keyValues);
+ if (primaryKeyFindDbContext != null)
+ {
+ return primaryKeyFindDbContext.Set().FindAsync(keyValues, cancellationToken);
+ }
+ return base.FindAsync(keyValues, cancellationToken);
+ }
+#endif
+#if EFCORE2
+ public override Task FindAsync(params object[] keyValues)
+ {
+ var primaryKeyFindDbContext = GetDbContextByKeyValue(keyValues);
+ if (primaryKeyFindDbContext != null)
+ {
+ return primaryKeyFindDbContext.Set().FindAsync(keyValues);
+ }
+ return base.FindAsync(keyValues);
+ }
+
+ public override Task FindAsync(object[] keyValues, CancellationToken cancellationToken)
+ {
+ var primaryKeyFindDbContext = GetDbContextByKeyValue(keyValues);
+ if (primaryKeyFindDbContext != null)
+ {
+ return primaryKeyFindDbContext.Set().FindAsync(keyValues, cancellationToken);
+ }
+ return base.FindAsync(keyValues, cancellationToken);
+ }
+#endif
+
+ private DbContext GetDbContextByKeyValue(params object[] keyValues)
+ {
+ if (keyValues.Length == 1)
+ {
+ var shardingEntityConfig = ShardingUtil.Parse(typeof(TEntity));
+ //单key字段
+ if (null != shardingEntityConfig.SinglePrimaryKeyFieldName)
+ {
+ var isShardingDataSource = typeof(TEntity).IsShardingDataSource();
+ var shardingDataSourceFieldIsKey = shardingEntityConfig.ShardingDataSourceFieldIsKey();
+ if (isShardingDataSource && !shardingDataSourceFieldIsKey)
+ return null;
+ var isShardingTable = typeof(TEntity).IsShardingTable();
+ var shardingTableFieldIsKey = shardingEntityConfig.ShardingTableFieldIsKey();
+ if (isShardingTable && !shardingTableFieldIsKey)
+ return null;
+ var primaryKeyValue = keyValues[0];
+ if (primaryKeyValue != null)
+ {
+ var dataSourceName = VirtualDataSource.GetDataSourceName(primaryKeyValue);
+ var tableTail = VirtualTableManager.GetTableTail(primaryKeyValue);
+ var routeTail = ShardingContainer.GetService().Create(tableTail);
+ return _context.GetDbContext(dataSourceName, false, routeTail);
+ }
+ }
+ }
+
+ return null;
+ }
+
}
}
\ No newline at end of file
diff --git a/src/ShardingCore/Extensions/ShardingEntityConfigExtension.cs b/src/ShardingCore/Extensions/ShardingEntityConfigExtension.cs
new file mode 100644
index 00000000..2d85587f
--- /dev/null
+++ b/src/ShardingCore/Extensions/ShardingEntityConfigExtension.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ShardingCore.Core.VirtualDatabase;
+
+namespace ShardingCore.Extensions
+{
+ public static class ShardingEntityConfigExtension
+ {
+ public static bool ShardingDataSourceFieldIsKey(this ShardingEntityConfig shardingEntityConfig)
+ {
+ if (string.IsNullOrWhiteSpace(shardingEntityConfig.ShardingDataSourceField))
+ return false;
+ return shardingEntityConfig.ShardingDataSourceField == shardingEntityConfig.SinglePrimaryKeyFieldName;
+ }
+ public static bool ShardingTableFieldIsKey(this ShardingEntityConfig shardingEntityConfig)
+ {
+ if (string.IsNullOrWhiteSpace(shardingEntityConfig.ShardingTableField))
+ return false;
+ return shardingEntityConfig.ShardingTableField == shardingEntityConfig.SinglePrimaryKeyFieldName;
+ }
+ }
+}
diff --git a/src/ShardingCore/Extensions/VirtualDataBaseExtension.cs b/src/ShardingCore/Extensions/VirtualDataBaseExtension.cs
index 9599912c..4f5f95cf 100644
--- a/src/ShardingCore/Extensions/VirtualDataBaseExtension.cs
+++ b/src/ShardingCore/Extensions/VirtualDataBaseExtension.cs
@@ -79,6 +79,14 @@ namespace ShardingCore.Extensions
var physicTable = virtualTableManager.GetVirtualTable(entity.GetType()).RouteTo(new ShardingTableRouteConfig(null, entity as IShardingTable, null))[0];
return physicTable.Tail;
}
+ public static string GetTableTail(this IVirtualTableManager virtualTableManager,
+ object shardingKeyValue) where TEntity : class
+ {
+ if (!typeof(TEntity).IsShardingTable())
+ return string.Empty;
+ var physicTable = virtualTableManager.GetVirtualTable(typeof(TEntity)).RouteTo(new ShardingTableRouteConfig(shardingKeyValue: shardingKeyValue))[0];
+ return physicTable.Tail;
+ }
public static bool IsVirtualDataSourceRoute(this Type routeType)
{
if (routeType == null)
diff --git a/src/ShardingCore/Extensions/VirtualDataSourceExtension.cs b/src/ShardingCore/Extensions/VirtualDataSourceExtension.cs
index 5fdc1704..42a97cfc 100644
--- a/src/ShardingCore/Extensions/VirtualDataSourceExtension.cs
+++ b/src/ShardingCore/Extensions/VirtualDataSourceExtension.cs
@@ -1,14 +1,12 @@
-using System;
+using Microsoft.EntityFrameworkCore;
+using ShardingCore.Core;
+using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
+using ShardingCore.Core.VirtualRoutes;
+using ShardingCore.Sharding.Abstractions;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
-using System.Text;
-using Microsoft.EntityFrameworkCore;
-using ShardingCore.Core;
-using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
-using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
-using ShardingCore.Core.VirtualRoutes;
-using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Extensions
{
@@ -21,7 +19,7 @@ namespace ShardingCore.Extensions
*/
public static class VirtualDataSourceExtension
{
- public static string GetDataSourceName(this IVirtualDataSource virtualDataSource,TEntity entity) where TShardingDbContext : DbContext, IShardingDbContext where TEntity : class
+ public static string GetDataSourceName(this IVirtualDataSource virtualDataSource,TEntity entity)where TEntity : class
{
if (!entity.IsShardingDataSource())
return virtualDataSource.DefaultDataSourceName;
@@ -30,12 +28,19 @@ namespace ShardingCore.Extensions
new ShardingDataSourceRouteConfig(shardingDataSource: entity as IShardingDataSource))[0];
}
- public static List GetDataSourceNames(this IVirtualDataSource virtualDataSource, Expression> where)
- where TShardingDbContext : DbContext, IShardingDbContext
+ public static List GetDataSourceNames(this IVirtualDataSource virtualDataSource, Expression> where)
where TEntity : class
{
return virtualDataSource.RouteTo(typeof(TEntity),new ShardingDataSourceRouteConfig(predicate: where))
.ToList();
}
+ public static string GetDataSourceName(this IVirtualDataSource virtualDataSource, object shardingKeyValue) where TEntity : class
+ {
+ if (!typeof(TEntity).IsShardingDataSource())
+ return virtualDataSource.DefaultDataSourceName;
+
+ return virtualDataSource.RouteTo(typeof(TEntity),
+ new ShardingDataSourceRouteConfig(shardingKeyValue:shardingKeyValue))[0];
+ }
}
}
diff --git a/src/ShardingCore/Sharding/AbstractShardingDbContext.cs b/src/ShardingCore/Sharding/AbstractShardingDbContext.cs
index c4ad9318..be65b604 100644
--- a/src/ShardingCore/Sharding/AbstractShardingDbContext.cs
+++ b/src/ShardingCore/Sharding/AbstractShardingDbContext.cs
@@ -39,6 +39,8 @@ namespace ShardingCore.Sharding
(IShardingDbContextExecutor)Activator.CreateInstance(
typeof(ShardingDbContextExecutor<>).GetGenericType0(this.GetType()),this);
}
+
+ IsExecutor = wrapOptionsExtension == null;
}
///
/// 读写分离优先级
@@ -60,11 +62,12 @@ namespace ShardingCore.Sharding
///
/// 是否是真正的执行者
///
- private bool isExecutor => _shardingDbContextExecutor == null;
+ public bool IsExecutor { get; }
+
//public void ShardingUpgrade()
//{
- // //isExecutor = true;
+ // //IsExecutor = true;
//}
public DbContext GetDbContext(string dataSourceName, bool parallelQuery, IRouteTail routeTail)
@@ -86,14 +89,14 @@ namespace ShardingCore.Sharding
public override EntityEntry Add(object entity)
{
- if (isExecutor)
+ if (IsExecutor)
base.Add(entity);
return CreateGenericDbContext(entity).Add(entity);
}
public override EntityEntry Add(TEntity entity)
{
- if (isExecutor)
+ if (IsExecutor)
return base.Add(entity);
return CreateGenericDbContext(entity).Add(entity);
}
@@ -104,14 +107,14 @@ namespace ShardingCore.Sharding
public override ValueTask> AddAsync(TEntity entity, CancellationToken cancellationToken = new CancellationToken())
{
- if (isExecutor)
+ if (IsExecutor)
return base.AddAsync(entity, cancellationToken);
return CreateGenericDbContext(entity).AddAsync(entity, cancellationToken);
}
public override ValueTask AddAsync(object entity, CancellationToken cancellationToken = new CancellationToken())
{
- if (isExecutor)
+ if (IsExecutor)
return base.AddAsync(entity, cancellationToken);
return CreateGenericDbContext(entity).AddAsync(entity, cancellationToken);
}
@@ -119,14 +122,14 @@ namespace ShardingCore.Sharding
#if EFCORE2
public override Task> AddAsync(TEntity entity, CancellationToken cancellationToken = new CancellationToken())
{
- if (isExecutor)
+ if (IsExecutor)
return base.AddAsync(entity, cancellationToken);
return CreateGenericDbContext(entity).AddAsync(entity, cancellationToken);
}
public override Task AddAsync(object entity, CancellationToken cancellationToken = new CancellationToken())
{
- if (isExecutor)
+ if (IsExecutor)
return base.AddAsync(entity, cancellationToken);
return CreateGenericDbContext(entity).AddAsync(entity, cancellationToken);
}
@@ -134,7 +137,7 @@ namespace ShardingCore.Sharding
public override void AddRange(params object[] entities)
{
- if (isExecutor)
+ if (IsExecutor)
{
base.AddRange(entities);
return;
@@ -157,7 +160,7 @@ namespace ShardingCore.Sharding
public override void AddRange(IEnumerable