Skip to content

Commit f5c2cbf

Browse files
committed
CSHARP-1326: Fix issue when using IGrouping as IEnumerable.
1 parent 6fd8f4b commit f5c2cbf

File tree

2 files changed

+91
-3
lines changed

2 files changed

+91
-3
lines changed

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/NewListExpressionToAggregationExpressionTranslator.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@ public static AggregationExpression Translate(TranslationContext context, NewExp
3434
{
3535
var argument = arguments[0];
3636
var argumentType = argument.Type;
37-
if (argumentType.IsConstructedGenericType && argumentType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
37+
if (argumentType.IsConstructedGenericType && argumentType.GetGenericTypeDefinition().Implements(typeof(IEnumerable<>)))
3838
{
39-
var argumentItemType = argumentType.GetGenericArguments()[0];
39+
var enumerableInterface = argumentType.GetIEnumerableGenericInterface();
40+
var argumentItemType = enumerableInterface.GetGenericArguments()[0];
4041
if (argumentItemType == listItemType)
4142
{
4243
var collectionExpression = argument;
43-
var collectionTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, collectionExpression);
44+
var collectionTranslation = ExpressionToAggregationExpressionTranslator.TranslateEnumerable(context, collectionExpression);
4445
var listSerializerType = typeof(EnumerableInterfaceImplementerSerializer<,>).MakeGenericType(listType, listItemType);
4546
var listItemSerializer = ArraySerializerHelper.GetItemSerializer(collectionTranslation.Serializer);
4647
var listSerializer = (IBsonSerializer)Activator.CreateInstance(listSerializerType, listItemSerializer);
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System.Collections.Generic;
17+
using System.Linq;
18+
using FluentAssertions;
19+
using MongoDB.Bson;
20+
using MongoDB.Bson.Serialization.Attributes;
21+
using Xunit;
22+
23+
namespace MongoDB.Driver.Tests.Linq.Linq3ImplementationTests.Jira
24+
{
25+
public class CSharp1326Tests : Linq3IntegrationTest
26+
{
27+
[Fact]
28+
public void Projection_of_ArrayOfDocuments_dictionary_keys_and_values_should_work()
29+
{
30+
var collection = CreateCollection();
31+
var parentIds = new int[] { 1, 2, 3 };
32+
var childrenFilter =
33+
Builders<Child>.Filter.In(c => c.ParentId, parentIds) &
34+
Builders<Child>.Filter.Eq(c => c.Gender, Gender.Male);
35+
36+
var aggregate = collection
37+
.Aggregate()
38+
.Match(childrenFilter)
39+
.Group(c => c.ParentId, g => new KeyValuePair<int, List<Child>>(g.Key, new List<Child>(g)));
40+
41+
var stages = Translate(collection, aggregate);
42+
AssertStages(
43+
stages,
44+
"{ $match : { ParentId : { $in : [1, 2, 3] }, Gender : 'Male' } }",
45+
"{ $group : { _id : '$ParentId', _elements : { $push : '$$ROOT' } } }",
46+
"{ $project : { Key : '$_id', Value : '$_elements', _id : 0 } }");
47+
48+
var results = aggregate.ToList().OrderBy(x => x.Key).ToList();
49+
results[0].Key.Should().Be(1);
50+
results[0].Value.Select(x => x.Id).Should().BeEquivalentTo(1, 2);
51+
results[1].Key.Should().Be(2);
52+
results[1].Value.Select(x => x.Id).Should().BeEquivalentTo(4);
53+
}
54+
55+
private IMongoCollection<Child> CreateCollection()
56+
{
57+
var collection = GetCollection<Child>("Children");
58+
59+
CreateCollection(
60+
collection,
61+
new Child { Id = 1, ParentId = 1, Gender = Gender.Male },
62+
new Child { Id = 2, ParentId = 1, Gender = Gender.Male },
63+
new Child { Id = 3, ParentId = 1, Gender = Gender.Female },
64+
new Child { Id = 4, ParentId = 2, Gender = Gender.Male },
65+
new Child { Id = 5, ParentId = 4, Gender = Gender.Male });
66+
67+
return collection;
68+
}
69+
70+
public class Parent
71+
{
72+
public int Id { get; set; }
73+
}
74+
75+
public class Child
76+
{
77+
public int Id { get; set; }
78+
79+
public int ParentId { get; set; }
80+
81+
[BsonRepresentation(BsonType.String)]
82+
public Gender Gender { get; set; }
83+
}
84+
85+
public enum Gender { Male, Female };
86+
}
87+
}

0 commit comments

Comments
 (0)