Skip to content

Commit b7b881f

Browse files
authored
Fix incorrect key lookup on WhereIdMatches (#343)
* Fix incorrect key lookup on WhereIdMatches With the new mapping change, the Id was looked up only on the specific entity definition, not any parent definitions. This would cause problems with derived types. * Add test
1 parent d2c7bfb commit b7b881f

4 files changed

Lines changed: 52 additions & 5 deletions

File tree

src/MongoFramework/Infrastructure/Commands/AddToBucketCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public IEnumerable<WriteModel<EntityBucket<TGroup, TSubEntity>>> GetModel(WriteM
4242
.Min(b => b.Min, itemTimeValue)
4343
.Max(b => b.Max, itemTimeValue)
4444
.SetOnInsert(b => b.BucketSize, BucketSize)
45-
.SetOnInsert(b => b.Id, entityDefinition.Key.KeyGenerator.Generate());
45+
.SetOnInsert(b => b.Id, entityDefinition.FindNearestKey().KeyGenerator.Generate());
4646

4747
yield return new UpdateOneModel<EntityBucket<TGroup, TSubEntity>>(filter, updateDefinition)
4848
{

src/MongoFramework/Infrastructure/Mapping/EntityDefinitionExtensions.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,24 @@ namespace MongoFramework.Infrastructure.Mapping
66
{
77
public static class EntityDefinitionExtensions
88
{
9-
public static PropertyDefinition GetIdProperty(this EntityDefinition definition)
9+
/// <summary>
10+
/// Finds the nearest <see cref="KeyDefinition"/> from <paramref name="definition"/>, recursively searching the base <see cref="EntityDefinition"/> if one exists.
11+
/// </summary>
12+
/// <param name="definition">The <see cref="EntityDefinition"/> to start the search from.</param>
13+
/// <returns>The key definition; otherwise <see langword="null"/> if one can not be found.</returns>
14+
public static KeyDefinition FindNearestKey(this EntityDefinition definition)
1015
{
1116
if (definition.Key is null)
1217
{
13-
return EntityMapping.GetOrCreateDefinition(definition.EntityType.BaseType).GetIdProperty();
18+
return EntityMapping.GetOrCreateDefinition(definition.EntityType.BaseType).FindNearestKey();
1419
}
1520

16-
return definition.Key?.Property;
21+
return definition.Key;
22+
}
23+
24+
public static PropertyDefinition GetIdProperty(this EntityDefinition definition)
25+
{
26+
return definition.FindNearestKey()?.Property;
1727
}
1828

1929
public static string GetIdName(this EntityDefinition definition)

src/MongoFramework/Linq/LinqExtensions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public static string ToQuery(this IQueryable queryable)
2727

2828
public static IQueryable<TEntity> WhereIdMatches<TEntity>(this IQueryable<TEntity> queryable, IEnumerable entityIds) where TEntity : class
2929
{
30-
var idProperty = EntityMapping.GetOrCreateDefinition(typeof(TEntity)).Key.Property;
30+
var idProperty = EntityMapping.GetOrCreateDefinition(typeof(TEntity)).GetIdProperty()
31+
?? throw new ArgumentException($"No Id property was found on entity type {typeof(TEntity)} or any base types");
3132
return queryable.WherePropertyMatches(idProperty, entityIds);
3233
}
3334

tests/MongoFramework.Tests/Linq/LinqExtensionsTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ public class LinqExtensionsModel
1717
{
1818
public string Id { get; set; }
1919
}
20+
public class WhereIdMatchesInheritanceBaseModel
21+
{
22+
public string Id { get; set; }
23+
}
24+
public class WhereIdMatchesInheritanceDerivedModel : WhereIdMatchesInheritanceBaseModel
25+
{
26+
public string Description { get; set; }
27+
}
2028
public class WhereIdMatchesGuidModel
2129
{
2230
public Guid Id { get; set; }
@@ -70,6 +78,34 @@ public void InvalidToQuery()
7078
LinqExtensions.ToQuery(null);
7179
}
7280

81+
[TestMethod]
82+
public void WhereIdMatches_BaseTypeWithId()
83+
{
84+
var connection = TestConfiguration.GetConnection();
85+
var context = new MongoDbContext(connection);
86+
var dbSet = new MongoDbSet<WhereIdMatchesInheritanceDerivedModel>(context);
87+
88+
var entityCollection = new[]
89+
{
90+
new WhereIdMatchesInheritanceDerivedModel { Description = "1" },
91+
new WhereIdMatchesInheritanceDerivedModel { Description = "2" },
92+
new WhereIdMatchesInheritanceDerivedModel { Description = "3" },
93+
new WhereIdMatchesInheritanceDerivedModel { Description = "4" }
94+
};
95+
dbSet.AddRange(entityCollection);
96+
context.SaveChanges();
97+
98+
var provider = new MongoFrameworkQueryProvider<WhereIdMatchesInheritanceDerivedModel>(connection);
99+
var queryable = new MongoFrameworkQueryable<WhereIdMatchesInheritanceDerivedModel>(provider);
100+
101+
var entityIds = entityCollection.Select(e => e.Id).Take(2);
102+
103+
var idMatchQueryable = LinqExtensions.WhereIdMatches(queryable, entityIds);
104+
105+
Assert.AreEqual(2, idMatchQueryable.Count());
106+
Assert.IsTrue(idMatchQueryable.ToList().All(e => entityIds.Contains(e.Id)));
107+
}
108+
73109
[TestMethod]
74110
public void WhereIdMatchesGuids()
75111
{

0 commit comments

Comments
 (0)