@@ -13,20 +13,24 @@ namespace EntityFrameworkCore.SqlServer.SimpleBulks.Extensions;
1313
1414public 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