1
1
using System ;
2
2
using System . Collections ;
3
+ using System . Collections . Concurrent ;
3
4
using System . Collections . Generic ;
4
5
using System . Data ;
5
6
using System . Data . Common ;
@@ -31,17 +32,21 @@ namespace NHibernate.Loader
31
32
/// Abstract superclass of object loading (and querying) strategies.
32
33
/// </summary>
33
34
/// <remarks>
34
- /// <p >
35
+ /// <para >
35
36
/// This class implements useful common functionality that concrete loaders would delegate to.
36
37
/// It is not intended that this functionality would be directly accessed by client code (Hence,
37
38
/// all methods of this class are declared <c>protected</c> or <c>private</c>.) This class relies heavily upon the
38
- /// <see cref="ILoadable" /> interface, which is the contract between this class and
39
+ /// <see cref="ILoadable" /> interface, which is the contract between this class and
39
40
/// <see cref="IEntityPersister" />s that may be loaded by it.
40
- /// </p >
41
- /// <p >
42
- /// The present implementation is able to load any number of columns of entities and at most
41
+ /// </para >
42
+ /// <para >
43
+ /// The present implementation is able to load any number of columns of entities and at most
43
44
/// one collection role per query.
44
- /// </p>
45
+ /// </para>
46
+ /// <para>
47
+ /// All this class members are thread safe. Entity and collection loaders are held in persisters shared among
48
+ /// sessions built from the same session factory. They must be thread safe.
49
+ /// </para>
45
50
/// </remarks>
46
51
/// <seealso cref="NHibernate.Persister.Entity.ILoadable"/>
47
52
public abstract partial class Loader
@@ -63,8 +68,8 @@ public abstract partial class Loader
63
68
/// <summary>
64
69
/// Caches subclass entity aliases for given persister index in <see cref="EntityPersisters"/> and subclass entity name
65
70
/// </summary>
66
- private readonly Dictionary < Tuple < int , string > , string [ ] [ ] > _subclassEntityAliasesMap = new Dictionary < Tuple < int , string > , string [ ] [ ] > ( ) ;
67
-
71
+ private readonly ConcurrentDictionary < Tuple < int , string > , string [ ] [ ] > _subclassEntityAliasesMap = new ConcurrentDictionary < Tuple < int , string > , string [ ] [ ] > ( ) ;
72
+
68
73
protected Loader ( ISessionFactoryImplementor factory )
69
74
{
70
75
_factory = factory ;
@@ -1103,14 +1108,9 @@ private void LoadFromResultSet(DbDataReader rs, int i, object obj, string instan
1103
1108
private string [ ] [ ] GetSubclassEntityAliases ( int i , ILoadable persister )
1104
1109
{
1105
1110
var cacheKey = System . Tuple . Create ( i , persister . EntityName ) ;
1106
- if ( _subclassEntityAliasesMap . TryGetValue ( cacheKey , out string [ ] [ ] cols ) )
1107
- {
1108
- return cols ;
1109
- }
1110
-
1111
- cols = EntityAliases [ i ] . GetSuffixedPropertyAliases ( persister ) ;
1112
- _subclassEntityAliasesMap [ cacheKey ] = cols ;
1113
- return cols ;
1111
+ return _subclassEntityAliasesMap . GetOrAdd (
1112
+ cacheKey ,
1113
+ k => EntityAliases [ i ] . GetSuffixedPropertyAliases ( persister ) ) ;
1114
1114
}
1115
1115
1116
1116
/// <summary>
0 commit comments