Skip to content

Commit 8bdef11

Browse files
committed
Cache
1 parent 93bfd2c commit 8bdef11

File tree

1 file changed

+46
-25
lines changed

1 file changed

+46
-25
lines changed

src/EntityFrameworkCore.SqlServer.SimpleBulks/Extensions/DbContextExtensions.cs

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,24 @@ namespace EntityFrameworkCore.SqlServer.SimpleBulks.Extensions;
1313

1414
public static class DbContextExtensions
1515
{
16-
private static readonly ConcurrentDictionary<Type, IReadOnlyList<ColumnInfor>> _propertiesCache = [];
17-
private static readonly ConcurrentDictionary<Type, TableInfor> _tableInfoCache = [];
18-
private static readonly ConcurrentDictionary<Type, IReadOnlyDictionary<string, string>> _columnNamesCache = [];
19-
private static readonly ConcurrentDictionary<Type, IReadOnlyDictionary<string, string>> _columnTypesCache = [];
20-
private static readonly ConcurrentDictionary<Type, IReadOnlyList<string>> _primaryKeysCache = [];
21-
private static readonly ConcurrentDictionary<Type, ColumnInfor> _outputIdCache = [];
22-
private static readonly ConcurrentDictionary<Type, IReadOnlyList<string>> _insertablePropertyNamesCache = [];
23-
private static readonly ConcurrentDictionary<Type, IReadOnlyList<string>> _allPropertyNamesCache = [];
16+
private readonly record struct CacheKey(Type DbContextType, Type EntityType);
17+
18+
private static readonly ConcurrentDictionary<CacheKey, IReadOnlyList<ColumnInfor>> _propertiesCache = [];
19+
private static readonly ConcurrentDictionary<CacheKey, TableInfor> _tableInfoCache = [];
20+
private static readonly ConcurrentDictionary<CacheKey, IReadOnlyDictionary<string, string>> _columnNamesCache = [];
21+
private static readonly ConcurrentDictionary<CacheKey, IReadOnlyDictionary<string, string>> _columnTypesCache = [];
22+
private static readonly ConcurrentDictionary<CacheKey, IReadOnlyList<string>> _primaryKeysCache = [];
23+
private static readonly ConcurrentDictionary<CacheKey, ColumnInfor> _outputIdCache = [];
24+
private static readonly ConcurrentDictionary<CacheKey, IReadOnlyList<string>> _insertablePropertyNamesCache = [];
25+
private static readonly ConcurrentDictionary<CacheKey, IReadOnlyList<string>> _allPropertyNamesCache = [];
26+
private static readonly ConcurrentDictionary<CacheKey, IReadOnlyList<string>> _allPropertyNamesWithoutRowVersionsCache = [];
2427

2528
public static TableInfor GetTableInfor(this DbContext dbContext, Type type)
2629
{
27-
return _tableInfoCache.GetOrAdd(type, (type) =>
30+
var cacheKey = new CacheKey(dbContext.GetType(), type);
31+
return _tableInfoCache.GetOrAdd(cacheKey, (key) =>
2832
{
29-
var entityType = dbContext.Model.FindEntityType(type);
33+
var entityType = dbContext.Model.FindEntityType(key.EntityType);
3034

3135
var schema = entityType.GetSchema();
3236
var tableName = entityType.GetTableName();
@@ -54,10 +58,11 @@ public static SqlTransaction GetCurrentSqlTransaction(this DbContext dbContext)
5458

5559
public static IReadOnlyList<ColumnInfor> GetProperties(this DbContext dbContext, Type type)
5660
{
57-
return _propertiesCache.GetOrAdd(type, (type) =>
61+
var cacheKey = new CacheKey(dbContext.GetType(), type);
62+
return _propertiesCache.GetOrAdd(cacheKey, (key) =>
5863
{
59-
var typeProperties = type.GetProperties().Select(x => new { x.Name, x.PropertyType });
60-
var entityProperties = dbContext.Model.FindEntityType(type)
64+
var typeProperties = key.EntityType.GetProperties().Select(x => new { x.Name, x.PropertyType });
65+
var entityProperties = dbContext.Model.FindEntityType(key.EntityType)
6166
.GetProperties();
6267

6368
var data = typeProperties.Join(entityProperties,
@@ -80,58 +85,74 @@ public static IReadOnlyList<ColumnInfor> GetProperties(this DbContext dbContext,
8085

8186
public static IReadOnlyDictionary<string, string> GetColumnNames(this DbContext dbContext, Type type)
8287
{
83-
return _columnNamesCache.GetOrAdd(type, (type) =>
88+
var cacheKey = new CacheKey(dbContext.GetType(), type);
89+
return _columnNamesCache.GetOrAdd(cacheKey, (key) =>
8490
{
85-
var properties = dbContext.GetProperties(type);
91+
var properties = dbContext.GetProperties(key.EntityType);
8692
return properties.ToDictionary(x => x.PropertyName, x => x.ColumnName);
8793
});
8894
}
8995

9096
public static IReadOnlyDictionary<string, string> GetColumnTypes(this DbContext dbContext, Type type)
9197
{
92-
return _columnTypesCache.GetOrAdd(type, (type) =>
98+
var cacheKey = new CacheKey(dbContext.GetType(), type);
99+
return _columnTypesCache.GetOrAdd(cacheKey, (key) =>
93100
{
94-
var properties = dbContext.GetProperties(type);
101+
var properties = dbContext.GetProperties(key.EntityType);
95102
return properties.ToDictionary(x => x.PropertyName, x => x.ColumnType);
96103
});
97104
}
98105

99106
public static IReadOnlyList<string> GetPrimaryKeys(this DbContext dbContext, Type type)
100107
{
101-
return _primaryKeysCache.GetOrAdd(type, (type) =>
108+
var cacheKey = new CacheKey(dbContext.GetType(), type);
109+
return _primaryKeysCache.GetOrAdd(cacheKey, (key) =>
102110
{
103-
var properties = dbContext.GetProperties(type);
111+
var properties = dbContext.GetProperties(key.EntityType);
104112
return properties.Where(x => x.IsPrimaryKey).Select(x => x.PropertyName).ToArray();
105113
});
106114
}
107115

108116
public static ColumnInfor GetOutputId(this DbContext dbContext, Type type)
109117
{
110-
return _outputIdCache.GetOrAdd(type, (type) =>
118+
var cacheKey = new CacheKey(dbContext.GetType(), type);
119+
return _outputIdCache.GetOrAdd(cacheKey, (key) =>
111120
{
112-
var properties = dbContext.GetProperties(type);
121+
var properties = dbContext.GetProperties(key.EntityType);
113122
return properties.Where(x => x.IsPrimaryKey && x.ValueGenerated == ValueGenerated.OnAdd).FirstOrDefault();
114123
});
115124
}
116125

117126
public static IReadOnlyList<string> GetInsertablePropertyNames(this DbContext dbContext, Type type)
118127
{
119-
return _insertablePropertyNamesCache.GetOrAdd(type, (type) =>
128+
var cacheKey = new CacheKey(dbContext.GetType(), type);
129+
return _insertablePropertyNamesCache.GetOrAdd(cacheKey, (key) =>
120130
{
121-
var properties = dbContext.GetProperties(type);
131+
var properties = dbContext.GetProperties(key.EntityType);
122132
return properties.Where(x => x.ValueGenerated == ValueGenerated.Never).Select(x => x.PropertyName).ToArray();
123133
});
124134
}
125135

126136
public static IReadOnlyList<string> GetAllPropertyNames(this DbContext dbContext, Type type)
127137
{
128-
return _allPropertyNamesCache.GetOrAdd(type, (type) =>
138+
var cacheKey = new CacheKey(dbContext.GetType(), type);
139+
return _allPropertyNamesCache.GetOrAdd(cacheKey, (key) =>
129140
{
130-
var properties = dbContext.GetProperties(type);
141+
var properties = dbContext.GetProperties(key.EntityType);
131142
return properties.Select(x => x.PropertyName).ToArray();
132143
});
133144
}
134145

146+
public static IReadOnlyList<string> GetAllPropertyNamesWithoutRowVersions(this DbContext dbContext, Type type)
147+
{
148+
var cacheKey = new CacheKey(dbContext.GetType(), type);
149+
return _allPropertyNamesWithoutRowVersionsCache.GetOrAdd(cacheKey, (key) =>
150+
{
151+
var properties = dbContext.GetProperties(key.EntityType);
152+
return properties.Where(x => !x.IsRowVersion).Select(x => x.PropertyName).ToArray();
153+
});
154+
}
155+
135156
public static IDbCommand CreateTextCommand(this DbContext dbContext, string commandText, BulkOptions options = null)
136157
{
137158
return dbContext.GetSqlConnection().CreateTextCommand(dbContext.GetCurrentSqlTransaction(), commandText, options);

0 commit comments

Comments
 (0)