Skip to content

Commit 9d87871

Browse files
sanych-sunrstam
authored andcommitted
CSHARP-4616: OfType should match derived types (#1075)
1 parent 0f624ca commit 9d87871

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToPipelineTranslators/OfTypeMethodToPipelineTranslator.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* limitations under the License.
1414
*/
1515

16+
using System.Linq;
1617
using System.Linq.Expressions;
1718
using MongoDB.Bson.Serialization;
1819
using MongoDB.Bson.Serialization.Serializers;
@@ -50,6 +51,11 @@ public static AstPipeline Translate(TranslationContext context, MethodCallExpres
5051
}
5152
var discriminatorField = AstFilter.Field(discriminatorElementName, BsonValueSerializer.Instance);
5253
var discriminatorValue = discriminatorConvention.GetDiscriminator(nominalType, actualType);
54+
if (discriminatorValue.IsBsonArray)
55+
{
56+
discriminatorValue = discriminatorValue.AsBsonArray.Last();
57+
}
58+
5359
var filter = AstFilter.Eq(discriminatorField, discriminatorValue); // note: OfType only works with hierarchical discriminators
5460
var actualSerializer = context.KnownSerializersRegistry.GetSerializer(expression);
5561
if (wrappedValueOutputSerializer != null)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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.Linq;
17+
using FluentAssertions;
18+
using MongoDB.Bson.Serialization.Attributes;
19+
using MongoDB.Driver.Linq;
20+
using Xunit;
21+
22+
namespace MongoDB.Driver.Tests.Linq.Linq3ImplementationTests.Translators.ExpressionToPipelineTranslators
23+
{
24+
public class OfTypeMethodToPipelineTranslatorTests: Linq3IntegrationTest
25+
{
26+
[Fact]
27+
public void OfType_should_return_expected_results()
28+
{
29+
var collection = CreateCollection();
30+
31+
AssertTypeOf<Account>(collection, "{ $match: { _t : 'Account' } }", 1, 2, 3);
32+
AssertTypeOf<Company>(collection, "{ $match: { _t : 'Company' } }", 1, 2);
33+
AssertTypeOf<Contact>(collection, "{ $match: { _t : 'Contact' } }", 3);
34+
}
35+
36+
private void AssertTypeOf<TDocument>(IMongoCollection<Entity> collection, string expectedStage, params int[] expectedIds)
37+
where TDocument: Entity
38+
{
39+
var queryable = collection
40+
.AsQueryable()
41+
.OfType<TDocument>();
42+
43+
var stages = Translate(collection, queryable);
44+
AssertStages(stages, expectedStage);
45+
46+
var results = queryable.ToList();
47+
results.Select(x => x.Id).Should().BeEquivalentTo(expectedIds);
48+
}
49+
50+
private IMongoCollection<Entity> CreateCollection()
51+
{
52+
var collection = GetCollection<Entity>("test");
53+
CreateCollection(
54+
collection,
55+
new Company { Id = 1 },
56+
new Company { Id = 2 },
57+
new Contact { Id = 3 });
58+
59+
return collection;
60+
}
61+
62+
[BsonDiscriminator(RootClass = true)]
63+
[BsonKnownTypes(typeof(Account), typeof(Contact), typeof(Company))]
64+
public abstract class Entity
65+
{
66+
public int Id { get; set; }
67+
}
68+
69+
public abstract class Account : Entity
70+
{
71+
}
72+
73+
public class Contact : Account
74+
{
75+
}
76+
77+
public class Company : Account
78+
{
79+
}
80+
}
81+
}

0 commit comments

Comments
 (0)