Skip to content

Commit d9efe1d

Browse files
committed
CSHARP-606: added support for type discriminated queries on fields.
1 parent 4d353d4 commit d9efe1d

File tree

3 files changed

+85
-13
lines changed

3 files changed

+85
-13
lines changed

Driver/Linq/Translators/PredicateTranslator.cs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
using MongoDB.Bson.Serialization.Options;
2828
using MongoDB.Driver.Builders;
2929
using MongoDB.Driver.Linq.Utils;
30+
using MongoDB.Bson.Serialization.Conventions;
3031

3132
namespace MongoDB.Driver.Linq
3233
{
@@ -1291,14 +1292,7 @@ private IMongoQuery BuildTypeComparisonQuery(Expression variableExpression, Expr
12911292
return null;
12921293
}
12931294

1294-
// TODO: would the object ever not be a ParameterExpression?
1295-
var parameterExpression = methodCallExpression.Object as ParameterExpression;
1296-
if (parameterExpression == null)
1297-
{
1298-
return null;
1299-
}
1300-
1301-
var serializationInfo = _serializationInfoHelper.GetSerializationInfo(parameterExpression);
1295+
var serializationInfo = _serializationInfoHelper.GetSerializationInfo(methodCallExpression.Object);
13021296
var nominalType = serializationInfo.NominalType;
13031297

13041298
var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(nominalType);
@@ -1308,22 +1302,28 @@ private IMongoQuery BuildTypeComparisonQuery(Expression variableExpression, Expr
13081302
return BuildBooleanQuery(true);
13091303
}
13101304

1305+
var elementName = discriminatorConvention.ElementName;
1306+
if (serializationInfo.ElementName != null)
1307+
{
1308+
elementName = string.Format("{0}.{1}", serializationInfo.ElementName, elementName);
1309+
}
1310+
13111311
if (discriminator.IsBsonArray)
13121312
{
13131313
var discriminatorArray = discriminator.AsBsonArray;
13141314
var queries = new IMongoQuery[discriminatorArray.Count + 1];
1315-
queries[0] = Query.Size(discriminatorConvention.ElementName, discriminatorArray.Count);
1315+
queries[0] = Query.Size(elementName, discriminatorArray.Count);
13161316
for (var i = 0; i < discriminatorArray.Count; i++)
13171317
{
1318-
queries[i + 1] = Query.EQ(string.Format("{0}.{1}", discriminatorConvention.ElementName, i), discriminatorArray[i]);
1318+
queries[i + 1] = Query.EQ(string.Format("{0}.{1}", elementName, i), discriminatorArray[i]);
13191319
}
13201320
return Query.And(queries);
13211321
}
13221322
else
13231323
{
13241324
return Query.And(
1325-
Query.NotExists(discriminatorConvention.ElementName + ".0"), // trick to check that element is not an array
1326-
Query.EQ(discriminatorConvention.ElementName, discriminator));
1325+
Query.NotExists(elementName + ".0"), // trick to check that element is not an array
1326+
Query.EQ(elementName, discriminator));
13271327
}
13281328
}
13291329

@@ -1344,7 +1344,13 @@ private IMongoQuery BuildTypeIsQuery(TypeBinaryExpression typeBinaryExpression)
13441344
discriminator = discriminator.AsBsonArray[discriminator.AsBsonArray.Count - 1];
13451345
}
13461346

1347-
return Query.EQ(discriminatorConvention.ElementName, discriminator);
1347+
var elementName = discriminatorConvention.ElementName;
1348+
var serializationInfo = _serializationInfoHelper.GetSerializationInfo(typeBinaryExpression.Expression);
1349+
if (serializationInfo.ElementName != null)
1350+
{
1351+
elementName = string.Format("{0}.{1}", serializationInfo.ElementName, elementName);
1352+
}
1353+
return Query.EQ(elementName, discriminator);
13481354
}
13491355

13501356
private string GetTrimCharsPattern(Expression trimCharsExpression)

DriverUnitTests/DriverUnitTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
<Compile Include="GridFS\MongoGridFSSettingsTests.cs" />
130130
<Compile Include="GridFS\MongoGridFSStreamTests.cs" />
131131
<Compile Include="GridFS\MongoGridFSTests.cs" />
132+
<Compile Include="Jira\CSharp606Tests.cs" />
132133
<Compile Include="Jira\CSharp598Tests.cs" />
133134
<Compile Include="Jira\CSharp538Tests.cs" />
134135
<Compile Include="Jira\CSharp532Tests.cs" />
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* Copyright 2010-2012 10gen 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;
17+
using System.Collections.Generic;
18+
using System.Linq;
19+
using System.Text;
20+
using NUnit.Framework;
21+
22+
using MongoDB.Bson;
23+
using MongoDB.Driver;
24+
using MongoDB.Driver.Linq;
25+
using MongoDB.Bson.Serialization.Attributes;
26+
using MongoDB.Driver.Builders;
27+
28+
namespace MongoDB.DriverUnitTests.Jira.CSharp606
29+
{
30+
[TestFixture]
31+
public class CSharp606Tests
32+
{
33+
[Test]
34+
public void TestTypeIsOnProperty()
35+
{
36+
IMongoQuery query = Query<TestClass>.Where(x => x.Prop is B);
37+
38+
Assert.AreEqual("{ \"Prop._t\" : \"B\" }", query.ToString());
39+
}
40+
41+
[Test]
42+
public void TestTypeOfComparisonOnProperty()
43+
{
44+
IMongoQuery query = Query<TestClass>.Where(x => x.Prop.GetType() == typeof(B));
45+
46+
Assert.AreEqual("{ \"Prop._t.0\" : { \"$exists\" : false }, \"Prop._t\" : \"B\" }", query.ToString());
47+
}
48+
49+
private class TestClass
50+
{
51+
public ObjectId Id { get; set; }
52+
53+
public A Prop { get; set; }
54+
}
55+
private class A
56+
{
57+
public string String { get; set; }
58+
}
59+
60+
private class B : A
61+
{
62+
public int Int { get; set; }
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)