Skip to content

Commit d07c310

Browse files
committed
Fix cache key when creating multi-map delegate for types with multiple key properties
1 parent 9a43fe6 commit d07c310

2 files changed

Lines changed: 13 additions & 9 deletions

File tree

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22
<PropertyGroup>
33
<Copyright>Copyright © Henk Mollema 2014</Copyright>
4-
<VersionPrefix>3.3.2</VersionPrefix>
4+
<VersionPrefix>3.3.3</VersionPrefix>
55
<Authors>Henk Mollema</Authors>
66
<LangVersion>latest</LangVersion>
77
<Nullable>enable</Nullable>

src/Dommel/AutoMultiMap.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -705,19 +705,23 @@ internal static Delegate CreateMapDelegate<T1, T2, T3, T4, T5, T6, T7, TReturn>(
705705
.ToArray();
706706

707707
var targetProperties = typeof(T1).GetProperties();
708-
var keyProperty = Resolvers.KeyProperties(typeof(T1)).First().Property;
708+
var keyProperties = Resolvers.KeyProperties(typeof(T1)).Select(x => x.Property);
709+
710+
// Create unique number from two integers
711+
// https://stackoverflow.com/a/14652569
712+
static int Pair(int a, int b) => (int)(((a + b) * (a + b + 1) * 0.5) + b);
709713

710714
T1 GetOrAdd(T1 target)
711715
{
712-
// Populate the dictionary with cached items keyed by the hash code
713-
// of the value of the primary key property. This way multi mapping
714-
// one-to-many relations don't produce multiple instances of the
715-
// same parent record.
716-
var id = keyProperty!.GetValue(target)!.GetHashCode();
717-
if (!results.TryGetValue(id, out var cachedItem))
716+
// Populate the dictionary with cached items keyed by the hash code of
717+
// the value of the primary key properties. This way multi mapping one-to-many
718+
// relations don't produce multiple instances of the same parent record.
719+
// Use paired hash codes of all key properties as cache key.
720+
var cacheKey = keyProperties.Aggregate(0, (x, prop) => Pair(x, prop.GetValue(target)!.GetHashCode()));
721+
if (!results.TryGetValue(cacheKey, out var cachedItem))
718722
{
719723
cachedItem = target;
720-
results[id] = cachedItem;
724+
results[cacheKey] = cachedItem;
721725
}
722726
return cachedItem;
723727
}

0 commit comments

Comments
 (0)