Skip to content

Commit 23331c4

Browse files
committed
CSHARP-4316: Ensure that LINQ3 only applies Nullable property translators to Nullables types and not properties with similar names.
1 parent 11c8da8 commit 23331c4

File tree

3 files changed

+61
-34
lines changed

3 files changed

+61
-34
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,5 +157,6 @@ Please see our [guidelines](CONTRIBUTING.md) for contributing to the driver.
157157
* Craig Wilson https://github.com/craiggwilson
158158
* Ming Yau Lee https://github.com/mingyaulee
159159
* Daniel Hegener [email protected]
160+
* Vladimir Setyaev [email protected]
160161

161162
If you have contributed and we have neglected to add you to this list please contact one of the maintainers to be added to the list (with apologies).

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
using MongoDB.Bson;
2222
using MongoDB.Bson.Serialization;
2323
using MongoDB.Bson.Serialization.Serializers;
24-
using MongoDB.Driver.Linq.Linq3Implementation.Ast;
2524
using MongoDB.Driver.Linq.Linq3Implementation.Ast.Expressions;
2625
using MongoDB.Driver.Linq.Linq3Implementation.Misc;
2726
using MongoDB.Driver.Linq.Linq3Implementation.Serializers;

tests/MongoDB.Driver.Tests/Linq/Linq3ImplementationTests/Jira/CSharp4316Tests.cs

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,84 @@
1-
using System.Linq;
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.Driver.Linq;
219
using Xunit;
320

421
namespace MongoDB.Driver.Tests.Linq.Linq3ImplementationTests.Jira
522
{
623
public class CSharp4316Tests : Linq3IntegrationTest
724
{
825
[Fact]
9-
public void Nullable_type_translate_should_work()
26+
public void Value_and_HasValue_should_work_when_properties_on_Nullable_type()
1027
{
11-
var collection = GetCollection<ModelContainNullableType>();
12-
var fluent = collection.Aggregate()
13-
.Group(x => new { Some = x.Some.Value, x.AnotherKeyGroup, x.Some.HasValue }, x => x.Select(t => t));
14-
15-
var stages = Translate(collection, fluent);
16-
var expected = new []
17-
{
18-
"{ $group : {'_id' : { Some : '$Some', AnotherKeyGroup : '$AnotherKeyGroup', HasValue : { $ne : ['$Some', null] }}, __agg0 : { '$push' : '$$ROOT'}}}",
19-
"{ $project : { '_v' : '$__agg0', _id : 0 } }"
20-
};
21-
22-
AssertStages(stages, expected);
28+
var collection = CreateCollection();
29+
var matchStage = "{ $match : { 'ActualNullable' : { $ne : null } } }";
30+
var projectStage = "{ $project : { Id : '$_id', Value : '$ActualNullable', HasValue : { $ne : ['$ActualNullable', null] }, _id : 0 } }";
31+
32+
var queryable = collection.AsQueryable()
33+
.Where(x => x.ActualNullable.HasValue)
34+
.Select(x => new { x.Id, x.ActualNullable.Value, x.ActualNullable.HasValue });
35+
36+
var stages = Translate(collection, queryable);
37+
AssertStages(stages, matchStage, projectStage);
38+
39+
var results = queryable.ToList();
40+
results.Select(r => r.Id).Should().Equal(2);
2341
}
2442

2543
[Fact]
26-
public void Type_contains_property_value_translate_should_work()
44+
public void Value_and_HasValue_should_work_when_properties_not_on_Nullable_type()
2745
{
28-
var collection = GetCollection<ModelWithoutNullable>();
29-
var fluent = collection.Aggregate()
30-
.Group(x => new { Key1 = x.Property.Value, Key2 = x.SomeData, Key3 = x.Property.HasValue}, x => x.Select(t => t));
31-
32-
var stages = Translate(collection, fluent);
33-
var expected = new []
34-
{
35-
"{ $group : {'_id' : { Key1 : '$Property.Value', Key2 : '$SomeData', Key3 : '$Property.HasValue' }, __agg0 : { '$push' : '$$ROOT'}}}",
36-
"{ $project : { '_v' : '$__agg0', _id : 0 } }"
37-
};
38-
AssertStages(stages, expected);
46+
var collection = CreateCollection();
47+
var matchStage = "{ $match : { 'OnlyLooksLikeNullable.HasValue' : true } }";
48+
var projectStage = "{ $project : { Id : '$_id', Value : '$OnlyLooksLikeNullable.Value', HasValue : '$OnlyLooksLikeNullable.HasValue', _id : 0 } }";
49+
50+
var queryable = collection
51+
.AsQueryable()
52+
.Where(x => x.OnlyLooksLikeNullable.HasValue)
53+
.Select(x => new { x.Id, Value = x.OnlyLooksLikeNullable.Value, HasValue = x.OnlyLooksLikeNullable.HasValue });
54+
55+
var stages = Translate(collection, queryable);
56+
AssertStages(stages, matchStage, projectStage);
57+
58+
var results = queryable.ToList();
59+
results.Select(r => r.Id).Should().Equal(1);
3960
}
4061

41-
public class ModelContainNullableType
62+
private IMongoCollection<C> CreateCollection()
4263
{
43-
public int? Some { get; set; }
44-
public float AnotherKeyGroup { get; set; }
64+
var collection = GetCollection<C>("C");
65+
66+
CreateCollection(
67+
collection,
68+
new C { Id = 1, OnlyLooksLikeNullable = new OnlyLooksLikeNullable { Value = "SomeValue", HasValue = true }, ActualNullable = null },
69+
new C { Id = 2, OnlyLooksLikeNullable = new OnlyLooksLikeNullable { Value = null, HasValue = false }, ActualNullable = true });
4570

71+
return collection;
4672
}
4773

48-
public class ModelWithoutNullable
74+
private class C
4975
{
50-
public CustomTypeLikeNullable Property { get; set; }
51-
public int SomeData { get; set; }
76+
public int Id { get; set; }
77+
public OnlyLooksLikeNullable OnlyLooksLikeNullable { get; set; }
78+
public bool? ActualNullable { get; set; }
5279
}
5380

54-
public class CustomTypeLikeNullable
81+
private class OnlyLooksLikeNullable
5582
{
5683
public string Value { get; set; }
5784
public bool HasValue { get; set; }

0 commit comments

Comments
 (0)