55// Created: 2007.09.26
66
77using System ;
8+ using System . Collections . Concurrent ;
89using System . Collections . Generic ;
910using System . Linq ;
1011using System . Reflection ;
@@ -26,7 +27,33 @@ internal sealed class ModelBuilder
2627 {
2728 private const string GeneratedTypeNameFormat = "{0}.EntitySetItems.{1}" ;
2829
29- private static ThreadSafeDictionary < string , Type > GeneratedTypes = ThreadSafeDictionary < string , Type > . Create ( new object ( ) ) ;
30+ private readonly struct TypeKey : IEquatable < TypeKey >
31+ {
32+ public readonly string Name ;
33+ public readonly Type OwnerType ;
34+ public readonly Type TargetType ;
35+
36+ public bool Equals ( TypeKey other ) => string . Equals ( Name , other . Name ) ;
37+
38+ public override bool Equals ( object obj ) => obj is TypeKey other && Equals ( other ) ;
39+
40+ public override int GetHashCode ( ) => ( Name ?? string . Empty ) . GetHashCode ( ) ;
41+
42+ public TypeKey ( string name , Type ownerType , Type targetType )
43+ {
44+ Name = name ;
45+ OwnerType = ownerType ;
46+ TargetType = targetType ;
47+ }
48+ }
49+
50+ private static readonly ConcurrentDictionary < TypeKey , Lazy < Type > > GeneratedTypes = new ConcurrentDictionary < TypeKey , Lazy < Type > > ( ) ;
51+
52+ private static readonly Func < TypeKey , Lazy < Type > > AuxiliaryTypeFactory = typeKey =>
53+ new Lazy < Type > ( ( ) => {
54+ var baseType = WellKnownOrmTypes . EntitySetItemOfT1T2 . CachedMakeGenericType ( typeKey . OwnerType , typeKey . TargetType ) ;
55+ return TypeHelper . CreateInheritedDummyType ( typeKey . Name , baseType , true ) ;
56+ } ) ;
3057
3158 private readonly BuildingContext context ;
3259 private readonly TypeBuilder typeBuilder ;
@@ -403,20 +430,14 @@ private void BuildAuxiliaryTypes(IEnumerable<AssociationInfo> associations)
403430
404431 private Type GenerateAuxiliaryType ( AssociationInfo association )
405432 {
406- var masterType = association . OwnerType . UnderlyingType ;
407- var slaveType = association . TargetType . UnderlyingType ;
408- var baseType = WellKnownOrmTypes . EntitySetItemOfT1T2 . MakeGenericType ( masterType , slaveType ) ;
433+ var ownerType = association . OwnerType . UnderlyingType ;
434+ var targetType = association . TargetType . UnderlyingType ;
409435
410436 var typeName = string . Format ( GeneratedTypeNameFormat ,
411- masterType . Namespace ,
437+ ownerType . Namespace ,
412438 context . NameBuilder . BuildAssociationName ( association ) ) ;
413439
414- var result = GeneratedTypes . GetValue ( typeName ,
415- ( _typeName , _baseType ) =>
416- TypeHelper . CreateInheritedDummyType ( _typeName , _baseType , true ) ,
417- baseType ) ;
418-
419- return result ;
440+ return GeneratedTypes . GetOrAdd ( new TypeKey ( typeName , ownerType , targetType ) , AuxiliaryTypeFactory ) . Value ;
420441 }
421442
422443 private void FindAndMarkInboundAndOutboundTypes ( BuildingContext context )
0 commit comments