Skip to content

Commit dd00b43

Browse files
committed
CSHARP-4572: Support casting from an interface to a concrete type in a filter expression.
1 parent ed795aa commit dd00b43

File tree

3 files changed

+87
-2
lines changed

3 files changed

+87
-2
lines changed

src/MongoDB.Driver/Linq/Linq3Implementation/Misc/TypeExtensions.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,13 @@ public static bool IsSameAsOrNullableOf(this Type type, Type valueType)
253253
return type == valueType || type.IsNullableOf(valueType);
254254
}
255255

256+
public static bool IsSubclassOfOrImplements(this Type type, Type baseTypeOrInterface)
257+
{
258+
return
259+
type.IsSubclassOf(baseTypeOrInterface) ||
260+
type.Implements(baseTypeOrInterface);
261+
}
262+
256263
public static bool IsTuple(this Type type)
257264
{
258265
return

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToFilterTranslators/ToFilterFieldTranslators/ConvertExpressionToFilterFieldTranslator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ private static bool IsConvertEnumToUnderlyingType(Type fieldType, Type targetTyp
8282

8383
private static bool IsConvertToBaseType(Type fieldType, Type targetType)
8484
{
85-
return fieldType.IsSubclassOf(targetType);
85+
return fieldType.IsSubclassOfOrImplements(targetType);
8686
}
8787

8888
private static bool IsConvertToDerivedType(Type fieldType, Type targetType)
8989
{
90-
return targetType.IsSubclassOf(fieldType);
90+
return targetType.IsSubclassOfOrImplements(fieldType);
9191
}
9292

9393
private static bool IsConvertToNullable(Type fieldType, Type targetType)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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.TestHelpers;
19+
using Xunit;
20+
21+
namespace MongoDB.Driver.Tests.Linq.Linq3Implementation.Jira
22+
{
23+
[Collection(RegisterObjectSerializerFixture.CollectionName)]
24+
public class CSharp4572Tests : Linq3IntegrationTest
25+
{
26+
[Fact]
27+
public void Builders_Filter_Eq_with_downcast_should_work()
28+
{
29+
var collection = GetCollection();
30+
var filter = Builders<IMyInterface>.Filter.Eq(x => ((MyClass)x).TestValue, 42);
31+
32+
var find = collection.Find(filter);
33+
34+
var renderedFilter = TranslateFindFilter(collection, find);
35+
renderedFilter.Should().Be("{ TestValue : 42 }");
36+
37+
var results = find.ToList();
38+
results.Select(x => x.Id).Should().Equal(2);
39+
}
40+
41+
[Fact]
42+
public void Where_with_downcast_should_work()
43+
{
44+
var collection = GetCollection();
45+
var filter = Builders<IMyInterface>.Filter.Eq(x => ((MyClass)x).TestValue, 42);
46+
47+
var queryable = collection.AsQueryable()
48+
.Where(x => ((MyClass)x).TestValue == 42);
49+
50+
var stages = Translate(collection, queryable);
51+
AssertStages(stages, "{ $match : { TestValue : 42 } }");
52+
53+
var results = queryable.ToList();
54+
results.Select(x => x.Id).Should().Equal(2);
55+
}
56+
57+
private IMongoCollection<IMyInterface> GetCollection()
58+
{
59+
var collection = GetCollection<IMyInterface>("test");
60+
CreateCollection(
61+
collection,
62+
new MyClass { Id = 1, TestValue = 1 },
63+
new MyClass { Id = 2, TestValue = 42 });
64+
return collection;
65+
}
66+
67+
public interface IMyInterface
68+
{
69+
int Id { get; set; }
70+
}
71+
72+
public class MyClass : IMyInterface
73+
{
74+
public int Id { get; set; }
75+
public int TestValue { get; set; }
76+
}
77+
}
78+
}

0 commit comments

Comments
 (0)