@@ -13,38 +13,39 @@ namespace Magic.IndexedDb.Helpers
1313{
1414 public static class PropertyMappingCache
1515 {
16- internal static readonly ConcurrentDictionary < Type , Dictionary < PropertyInfo , MagicPropertyEntry > > _propertyCache = new ( ) ;
17-
16+ internal static readonly ConcurrentDictionary < string , Dictionary < string , MagicPropertyEntry > > _propertyCache = new ( ) ;
17+
1818 /// <summary>
1919 /// Gets the C# property name given a JavaScript property name.
2020 /// </summary>
2121 public static string GetCsharpPropertyName < T > ( string jsPropertyName )
2222 {
23- EnsureTypeIsCached < T > ( ) ;
24-
25- var properties = _propertyCache [ typeof ( T ) ] ;
26- return properties . FirstOrDefault ( kvp => kvp . Value . JsPropertyName == jsPropertyName ) . Value . CsharpPropertyName ?? jsPropertyName ;
27- }
28-
29- /// <summary>
30- /// Gets the C# property name given a PropertyInfo reference.
31- /// </summary>
32- public static string GetCsharpPropertyName < T > ( PropertyInfo property )
33- {
34- return GetCsharpPropertyName < T > ( property . Name ) ;
23+ return GetCsharpPropertyName ( jsPropertyName , typeof ( T ) ) ;
3524 }
3625
3726 /// <summary>
38- /// Gets the JavaScript property name (ColumnName) given a C# property name.
27+ /// Gets the C# property name given a JavaScript property name.
3928 /// </summary>
40- public static string GetJsPropertyName ( string csharpPropertyName , Type type )
29+ public static string GetCsharpPropertyName ( string jsPropertyName , Type type )
4130 {
4231 EnsureTypeIsCached ( type ) ;
32+ string typeKey = type . FullName ! ;
4333
44- var properties = _propertyCache [ type ] ;
45- return properties . FirstOrDefault ( kvp => kvp . Key . Name == csharpPropertyName ) . Value . JsPropertyName ?? csharpPropertyName ;
46- }
34+ try
35+ {
36+ if ( _propertyCache . TryGetValue ( typeKey , out var properties ) &&
37+ properties . TryGetValue ( jsPropertyName , out var entry ) )
38+ {
39+ return entry . CsharpPropertyName ;
40+ }
41+ }
42+ catch ( Exception ex )
43+ {
44+ throw new Exception ( $ "Error retrieving C# property name for JS property '{ jsPropertyName } ' in type { type . FullName } .", ex ) ;
45+ }
4746
47+ return jsPropertyName ; // Fallback to original name if not found
48+ }
4849
4950 /// <summary>
5051 /// Gets the JavaScript property name (ColumnName) given a C# property name.
@@ -54,20 +55,38 @@ public static string GetJsPropertyName<T>(string csharpPropertyName)
5455 return GetJsPropertyName ( csharpPropertyName , typeof ( T ) ) ;
5556 }
5657
57- /// <summary>
58- /// Gets the JavaScript property name (ColumnName) given a PropertyInfo reference.
59- /// </summary>
60- public static string GetJsPropertyName ( PropertyInfo property , Type type )
58+ public static string GetJsPropertyName < T > ( PropertyInfo prop )
6159 {
62- return GetJsPropertyName ( property . Name , type ) ;
60+ return GetJsPropertyName ( prop . Name , typeof ( T ) ) ;
61+ }
62+
63+ public static string GetJsPropertyName ( PropertyInfo prop , Type type )
64+ {
65+ return GetJsPropertyName ( prop . Name , type ) ;
6366 }
6467
6568 /// <summary>
66- /// Gets the JavaScript property name (ColumnName) given a PropertyInfo reference .
69+ /// Gets the JavaScript property name (ColumnName) given a C# property name .
6770 /// </summary>
68- public static string GetJsPropertyName < T > ( PropertyInfo property )
71+ public static string GetJsPropertyName ( string csharpPropertyName , Type type )
6972 {
70- return GetJsPropertyName < T > ( property . Name ) ;
73+ EnsureTypeIsCached ( type ) ;
74+ string typeKey = type . FullName ! ;
75+
76+ try
77+ {
78+ if ( _propertyCache . TryGetValue ( typeKey , out var properties ) &&
79+ properties . TryGetValue ( csharpPropertyName , out var entry ) )
80+ {
81+ return entry . JsPropertyName ;
82+ }
83+ }
84+ catch ( Exception ex )
85+ {
86+ throw new Exception ( $ "Error retrieving JS property name for C# property '{ csharpPropertyName } ' in type { type . FullName } .", ex ) ;
87+ }
88+
89+ return csharpPropertyName ; // Fallback to original name if not found
7190 }
7291
7392 /// <summary>
@@ -84,17 +103,30 @@ public static MagicPropertyEntry GetPropertyEntry<T>(string propertyName)
84103 public static MagicPropertyEntry GetPropertyEntry ( string propertyName , Type type )
85104 {
86105 EnsureTypeIsCached ( type ) ;
106+ string typeKey = type . FullName ! ;
107+
108+ try
109+ {
110+ if ( _propertyCache . TryGetValue ( typeKey , out var properties ) &&
111+ properties . TryGetValue ( propertyName , out var entry ) )
112+ {
113+ return entry ;
114+ }
115+ }
116+ catch ( Exception ex )
117+ {
118+ throw new Exception ( $ "Error retrieving property entry for '{ propertyName } ' in type { type . FullName } .", ex ) ;
119+ }
87120
88- var properties = _propertyCache [ type ] ;
89- return properties . FirstOrDefault ( kvp => kvp . Key . Name == propertyName ) . Value ;
121+ throw new Exception ( $ "Error: Property '{ propertyName } ' not found in type { type . FullName } .") ;
90122 }
91123
92124 /// <summary>
93125 /// Gets the cached MagicPropertyEntry for a given PropertyInfo reference.
94126 /// </summary>
95127 public static MagicPropertyEntry GetPropertyEntry < T > ( PropertyInfo property )
96128 {
97- return GetPropertyEntry < T > ( property . Name ) ;
129+ return GetPropertyEntry ( property . Name , typeof ( T ) ) ;
98130 }
99131
100132 /// <summary>
@@ -105,6 +137,7 @@ public static MagicPropertyEntry GetPropertyEntry(PropertyInfo property, Type ty
105137 return GetPropertyEntry ( property . Name , type ) ;
106138 }
107139
140+
108141 /// <summary>
109142 /// Ensures that both schema and property caches are built for the given type.
110143 /// </summary>
@@ -115,40 +148,44 @@ internal static void EnsureTypeIsCached<T>()
115148
116149 internal static void EnsureTypeIsCached ( Type type )
117150 {
118- // Ensures both caches are built in a single operation
119- if ( ! _propertyCache . ContainsKey ( type ) || ! SchemaHelper . _schemaCache . ContainsKey ( type ) )
151+ string typeKey = type . FullName ! ;
152+
153+ // Avoid re-registering types if the typeKey already exists
154+ if ( _propertyCache . ContainsKey ( typeKey ) )
155+ return ;
156+
157+ // Ensure schema metadata is cached
158+ SchemaHelper . EnsureSchemaIsCached ( type ) ;
159+
160+ // Initialize the dictionary for this type
161+ var propertyEntries = new Dictionary < string , MagicPropertyEntry > ( ) ;
162+
163+ foreach ( var property in type . GetProperties ( BindingFlags . Public | BindingFlags . NonPublic | BindingFlags . Instance | BindingFlags . FlattenHierarchy ) )
120164 {
121- SchemaHelper . _schemaCache . GetOrAdd ( type , t => t . GetCustomAttribute < MagicTableAttribute > ( ) ) ;
165+ string propertyKey = property . Name ; // Now stored as string, not PropertyInfo
122166
123- _propertyCache . GetOrAdd ( type , t =>
167+ var columnAttribute = property . GetCustomAttributes ( )
168+ . FirstOrDefault ( attr => attr is IColumnNamed ) as IColumnNamed ;
169+
170+ if ( columnAttribute != null && string . IsNullOrWhiteSpace ( columnAttribute . ColumnName ) )
124171 {
125- var propertyEntries = new Dictionary < PropertyInfo , MagicPropertyEntry > ( ) ;
126-
127- foreach ( var property in t . GetProperties ( BindingFlags . Public | BindingFlags . Instance ) )
128- {
129- var columnAttribute = property . GetCustomAttributes ( )
130- . FirstOrDefault ( attr => attr is IColumnNamed ) as IColumnNamed ;
131-
132- if ( columnAttribute != null && string . IsNullOrWhiteSpace ( columnAttribute . ColumnName ) )
133- {
134- columnAttribute = null ;
135- }
136-
137- var magicEntry = new MagicPropertyEntry (
138- property ,
139- columnAttribute ,
140- property . IsDefined ( typeof ( MagicIndexAttribute ) , inherit : true ) ,
141- property . IsDefined ( typeof ( MagicUniqueIndexAttribute ) , inherit : true ) ,
142- property . IsDefined ( typeof ( MagicPrimaryKeyAttribute ) , inherit : true ) ,
143- property . IsDefined ( typeof ( MagicNotMappedAttribute ) , inherit : true )
144- ) ;
145-
146- propertyEntries [ property ] = magicEntry ;
147- }
148-
149- return propertyEntries ;
150- } ) ;
172+ columnAttribute = null ;
173+ }
174+
175+ var magicEntry = new MagicPropertyEntry (
176+ property ,
177+ columnAttribute ,
178+ property . IsDefined ( typeof ( MagicIndexAttribute ) , inherit : true ) ,
179+ property . IsDefined ( typeof ( MagicUniqueIndexAttribute ) , inherit : true ) ,
180+ property . IsDefined ( typeof ( MagicPrimaryKeyAttribute ) , inherit : true ) ,
181+ property . IsDefined ( typeof ( MagicNotMappedAttribute ) , inherit : true )
182+ ) ;
183+
184+ propertyEntries [ propertyKey ] = magicEntry ; // Store property entry with string key
151185 }
186+
187+ // Cache the properties for this type
188+ _propertyCache [ typeKey ] = propertyEntries ;
152189 }
153190 }
154191}
0 commit comments