Skip to content

Commit 4300290

Browse files
committed
完成优化自动追踪性能提升1000%并且发布了x.3.0.5版本
1 parent 2a13b37 commit 4300290

File tree

10 files changed

+88
-25
lines changed

10 files changed

+88
-25
lines changed

nuget-publish.bat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
:start
22
::定义版本
3-
set EFCORE2=2.3.0.04
4-
set EFCORE3=3.3.0.04
5-
set EFCORE5=5.3.0.04
3+
set EFCORE2=2.3.0.05
4+
set EFCORE3=3.3.0.05
5+
set EFCORE5=5.3.0.05
66

77
::删除所有bin与obj下的文件
88
@echo off

samples/Sample.BulkConsole/Program.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ static void Main(string[] args)
3030
{
3131
o.CreateShardingTableOnStart = true;
3232
o.EnsureCreatedWithOutShardingTable = true;
33+
o.AutoTrackEntity = true;
3334
})
3435
.AddShardingQuery((conStr, builder) => builder.UseSqlServer(conStr).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking))
3536
.AddShardingTransaction((connection, builder) => builder.UseSqlServer(connection))
@@ -80,8 +81,40 @@ static void Main(string[] args)
8081

8182
var b = DateTime.Now.Date.AddDays(-3);
8283
var queryable = myShardingDbContext.Set<Order>().Where(o => o.CreateTime >= b).OrderBy(o => o.CreateTime);
84+
8385
var startNew1 = Stopwatch.StartNew();
8486

87+
88+
startNew1.Restart();
89+
var list2 = queryable.Take(1000).ToList();
90+
startNew1.Stop();
91+
Console.WriteLine($"获取1000条用时:{startNew1.ElapsedMilliseconds}毫秒");
92+
93+
startNew1.Restart();
94+
var list = queryable.Take(10).ToList();
95+
startNew1.Stop();
96+
Console.WriteLine($"获取10条用时:{startNew1.ElapsedMilliseconds}毫秒");
97+
98+
99+
startNew1.Restart();
100+
var list1 = queryable.Take(100).ToList();
101+
startNew1.Stop();
102+
Console.WriteLine($"获取100条用时:{startNew1.ElapsedMilliseconds}毫秒");
103+
104+
105+
startNew1.Restart();
106+
var list3 = queryable.Take(10000).ToList();
107+
startNew1.Stop();
108+
Console.WriteLine($"获取100000条用时:{startNew1.ElapsedMilliseconds}毫秒");
109+
110+
111+
112+
startNew1.Restart();
113+
var list4 = queryable.Take(20000).ToList();
114+
startNew1.Stop();
115+
Console.WriteLine($"获取20000条用时:{startNew1.ElapsedMilliseconds}毫秒");
116+
117+
85118
int skip = 0, take = 1000;
86119
for (int i = 20000; i < 30000; i++)
87120
{

samples/Sample.BulkConsole/Sample.BulkConsole.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
</PropertyGroup>
77
<ItemGroup>
88
<PackageReference Include="EFCore.BulkExtensions" Version="5.3.9" />
9-
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.9" />
9+
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.10" />
1010
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
1111
</ItemGroup>
1212
<ItemGroup>

src/ShardingCore/Extensions/DbContextExtension.cs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using System;
22
using System.Collections.Concurrent;
33
using System.Collections.Generic;
4+
using System.Diagnostics;
45
using System.Linq;
56
using Microsoft.EntityFrameworkCore;
7+
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
68
using Microsoft.EntityFrameworkCore.Infrastructure;
79
using Microsoft.EntityFrameworkCore.Infrastructure.Internal;
810
using Microsoft.EntityFrameworkCore.Internal;
@@ -155,16 +157,38 @@ public static object GetModelCacheSyncObject(this DbContext dbContext)
155157

156158
private static object sLock = new object();
157159

160+
161+
public static IEnumerable<object> GetPrimaryKeyValues<TEntity>(TEntity entity,IKey primaryKey) where TEntity : class
162+
{
163+
return primaryKey.Properties.Select(o => entity.GetPropertyValue(o.Name));
164+
}
165+
158166
public static TEntity GetAttachedEntity<TEntity>(this DbContext context, TEntity entity) where TEntity:class
159167
{
160168
if (entity == null) { throw new ArgumentNullException(nameof(entity)); }
161-
162-
var primaryKeyValue = ShardingKeyUtil.GetPrimaryKeyValues(entity);
169+
var entityPrimaryKey = context.Model.FindEntityType(entity.GetType()).FindPrimaryKey();
170+
var primaryKeyValue = GetPrimaryKeyValues(entity, entityPrimaryKey).ToArray();
163171
if (primaryKeyValue.IsEmpty())
164172
return null;
165-
var entry = context.ChangeTracker.Entries<TEntity>().FirstOrDefault(e =>e.State != EntityState.Detached&&primaryKeyValue.SequenceEqual(ShardingKeyUtil.GetPrimaryKeyValues(e.Entity)));
166-
167-
return entry?.Entity;
173+
var dbContextDependencies = (IDbContextDependencies)typeof(DbContext).GetTypePropertyValue(context, "DbContextDependencies");
174+
var stateManager = dbContextDependencies.StateManager;
175+
176+
//var entityIKey = ShardingKeyUtil.GetEntityIKey(entity);
177+
var internalEntityEntry = stateManager.TryGetEntry(entityPrimaryKey, primaryKeyValue);
178+
179+
if (internalEntityEntry == null)
180+
return null;
181+
return (TEntity)internalEntityEntry.Entity;
182+
//sp.Restart();
183+
184+
//var entityEntries = context.ChangeTracker.Entries<TEntity>();
185+
//sp.Stop();
186+
//Console.WriteLine($"ChangeTracker.Entries:{sp.ElapsedMilliseconds}毫秒");
187+
//sp.Restart();
188+
//var entry = entityEntries.Where(e => e.State != EntityState.Detached && primaryKeyValue.SequenceEqual(ShardingKeyUtil.GetPrimaryKeyValues(e.Entity))).FirstOrDefault();
189+
//sp.Stop();
190+
//Console.WriteLine($"ChangeTracker.FirstOrDefault:{sp.ElapsedMilliseconds}毫秒");
191+
//return entry?.Entity;
168192
}
169193

170194
}

src/ShardingCore/Sharding/MergeEngines/TrackerEnumerators/AsyncTrackerEnumerator.cs renamed to src/ShardingCore/Sharding/Enumerators/TrackerEnumerators/AsyncTrackerEnumerator.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
1+
using System.Collections.Generic;
42
using System.Threading;
53
using System.Threading.Tasks;
6-
using Microsoft.EntityFrameworkCore;
7-
using ShardingCore.Core.TrackerManagers;
84
using ShardingCore.Extensions;
9-
using ShardingCore.Sharding.Abstractions;
105

11-
namespace ShardingCore.Sharding.StreamMergeEngines.TrackerEnumerators
6+
namespace ShardingCore.Sharding.Enumerators.TrackerEnumerators
127
{
138
/*
149
* @Author: xjm

src/ShardingCore/Sharding/MergeEngines/TrackerEnumerators/TrackerEnumerator.cs renamed to src/ShardingCore/Sharding/Enumerators/TrackerEnumerators/TrackerEnumerator.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
using System;
2-
using System.Collections;
1+
using System.Collections;
32
using System.Collections.Generic;
4-
using System.Text;
5-
using Microsoft.EntityFrameworkCore;
63
using ShardingCore.Extensions;
74

8-
namespace ShardingCore.Sharding.StreamMergeEngines.TrackerEnumerators
5+
namespace ShardingCore.Sharding.Enumerators.TrackerEnumerators
96
{
107
/*
118
* @Author: xjm
@@ -51,7 +48,9 @@ private T GetCurrent()
5148
var genericDbContext = _streamMergeContext.GetShardingDbContext().CreateGenericDbContext(c);
5249
var attachedEntity = genericDbContext.GetAttachedEntity(c);
5350
if (attachedEntity == null)
51+
{
5452
genericDbContext.Attach(current);
53+
}
5554
else
5655
{
5756
return (T)attachedEntity;

src/ShardingCore/Sharding/MergeEngines/EnumeratorStreamMergeEngines/AsyncEnumeratorStreamMergeEngine.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
using System.Threading;
44
using Microsoft.EntityFrameworkCore;
55
using ShardingCore.Sharding.Abstractions;
6+
using ShardingCore.Sharding.Enumerators.TrackerEnumerators;
67
using ShardingCore.Sharding.ShardingQueryExecutors;
7-
using ShardingCore.Sharding.StreamMergeEngines.TrackerEnumerators;
88

99
namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
1010
{

src/ShardingCore/Sharding/StreamMergeContext.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,14 +228,16 @@ public bool IsUseShardingTrack(Type entityType)
228228
}
229229
private bool QueryTrack()
230230
{
231-
231+
var shardingDbContext = (DbContext)_shardingDbContext;
232+
if (!shardingDbContext.ChangeTracker.AutoDetectChangesEnabled)
233+
return false;
232234
if (IsNoTracking.HasValue)
233235
{
234236
return !IsNoTracking.Value;
235237
}
236238
else
237239
{
238-
return ((DbContext)_shardingDbContext).ChangeTracker.QueryTrackingBehavior ==
240+
return shardingDbContext.ChangeTracker.QueryTrackingBehavior ==
239241
QueryTrackingBehavior.TrackAll;
240242
}
241243
}

src/ShardingCore/ShardingDbContextBootstrapper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public void Init()
7878
EnsureCreated(context, dataSourceName);
7979
foreach (var entity in context.Model.GetEntityTypes())
8080
{
81-
ShardingKeyUtil.ParsePrimaryKeyName(entity);
81+
//ShardingKeyUtil.ParsePrimaryKeyName(entity);
8282
var entityType = entity.ClrType;
8383
//添加追踪模型
8484
_trackerManager.AddDbContextModel(entityType);

src/ShardingCore/Utils/ShardingKeyUtil.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ public static IEnumerable<object> GetPrimaryKeyValues(object entity)
4444

4545
return primaryKey.Properties.Select(o => entity.GetPropertyValue(o.Name));
4646
}
47+
public static IKey GetEntityIKey(object entity)
48+
{
49+
var entityType = entity.GetType();
50+
if (!_caches.TryGetValue(entityType, out var primaryKey))
51+
{
52+
return null;
53+
}
54+
55+
return primaryKey;
56+
}
4757

4858

4959

0 commit comments

Comments
 (0)