Skip to content

Commit a8454b3

Browse files
committed
NameBuilder concurrency issue fix
1 parent ac5a5bb commit a8454b3

1 file changed

Lines changed: 9 additions & 28 deletions

File tree

Orm/Xtensive.Orm/Orm/Providers/NameBuilder.cs

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// Created: 2007.08.27
66

77
using System;
8+
using System.Collections.Concurrent;
89
using System.Collections.Generic;
910
using System.Linq;
1011
using System.Reflection;
@@ -19,6 +20,7 @@
1920
using Xtensive.Orm.Weaving;
2021
using Xtensive.Reflection;
2122
using FieldInfo = Xtensive.Orm.Model.FieldInfo;
23+
using Module = System.Reflection.Module;
2224
using TypeInfo = Xtensive.Orm.Model.TypeInfo;
2325

2426
namespace Xtensive.Orm.Providers
@@ -36,8 +38,11 @@ public sealed class NameBuilder
3638
private const string ReferenceForeignKeyFormat = "FK_{0}_{1}_{2}";
3739
private const string HierarchyForeignKeyFormat = "FK_{0}_{1}";
3840

39-
private readonly Dictionary<Pair<Type, string>, string> fieldNameCache = new Dictionary<Pair<Type, string>, string>();
40-
private readonly object _lock = new object();
41+
private readonly ConcurrentDictionary<PropertyInfo, string> fieldNameCache =
42+
new ConcurrentDictionary<PropertyInfo, string>();
43+
private static readonly Func<PropertyInfo, string> _fieldNameCacheValueFactory =
44+
field => field.GetAttribute<OverrideFieldNameAttribute>()?.Name ?? field.Name;
45+
4146
private readonly int maxIdentifierLength;
4247
private readonly NamingConvention namingConvention;
4348
private readonly bool isMultidatabase;
@@ -182,38 +187,14 @@ public string BuildFieldName(FieldDef field)
182187
}
183188

184189
private string BuildFieldNameInternal(PropertyInfo propertyInfo)
185-
{
186-
var key = new Pair<Type, string>(propertyInfo.ReflectedType, propertyInfo.Name);
187-
188-
lock (fieldNameCache) {
189-
string result;
190-
if (fieldNameCache.TryGetValue(key, out result))
191-
return result;
192-
var attribute = propertyInfo.GetAttribute<OverrideFieldNameAttribute>();
193-
if (attribute!=null) {
194-
result = attribute.Name;
195-
fieldNameCache.Add(key, result);
196-
return result;
197-
}
198-
}
199-
200-
return propertyInfo.Name;
201-
}
190+
=> fieldNameCache.GetOrAdd(propertyInfo, _fieldNameCacheValueFactory);
202191

203192
/// <summary>
204193
/// Builds the name of the field.
205194
/// </summary>
206195
/// <param name="propertyInfo">The property info.</param>
207196
public string BuildFieldName(PropertyInfo propertyInfo)
208-
{
209-
lock (fieldNameCache) {
210-
var key = new Pair<Type, string>(propertyInfo.ReflectedType, propertyInfo.Name);
211-
string result;
212-
return fieldNameCache.TryGetValue(key, out result)
213-
? result
214-
: propertyInfo.Name;
215-
}
216-
}
197+
=> fieldNameCache.TryGetValue(propertyInfo, out string result) ? result : propertyInfo.Name;
217198

218199
/// <summary>
219200
/// Builds the name of the explicitly implemented field.

0 commit comments

Comments
 (0)