Skip to content

Commit ddf2e90

Browse files
committed
Added support for selecting elements with ElementAt.
1 parent ca4e15c commit ddf2e90

File tree

3 files changed

+213
-0
lines changed

3 files changed

+213
-0
lines changed

Driver/Linq/Utils/BsonSerializationInfoHelper.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,11 @@ private BsonSerializationInfo GetSerializationInfo(IBsonSerializer serializer, E
195195
return GetSerializationInfoGetItem(serializer, methodCallExpression);
196196
}
197197

198+
if (methodCallExpression != null && methodCallExpression.Method.Name == "ElementAt")
199+
{
200+
return GetSerializationInfoElementAt(serializer, methodCallExpression);
201+
}
202+
198203
return null;
199204
}
200205

@@ -260,6 +265,31 @@ private BsonSerializationInfo GetSerializationInfoGetItem(IBsonSerializer serial
260265
return null;
261266
}
262267

268+
private BsonSerializationInfo GetSerializationInfoElementAt(IBsonSerializer serializer, MethodCallExpression methodCallExpression)
269+
{
270+
var declaringType = methodCallExpression.Method.DeclaringType;
271+
if (declaringType == typeof(Enumerable) || declaringType == typeof(Queryable))
272+
{
273+
var arraySerializationInfo = GetSerializationInfo(serializer, methodCallExpression.Arguments[0]);
274+
if (arraySerializationInfo != null)
275+
{
276+
var itemSerializationInfoProvider = arraySerializationInfo.Serializer as IBsonItemSerializationInfoProvider;
277+
if (itemSerializationInfoProvider != null)
278+
{
279+
var index = (int)((ConstantExpression)methodCallExpression.Arguments[1]).Value;
280+
var itemSerializationInfo = itemSerializationInfoProvider.GetItemSerializationInfo();
281+
return new BsonSerializationInfo(
282+
arraySerializationInfo.ElementName + "." + index.ToString(),
283+
itemSerializationInfo.Serializer,
284+
itemSerializationInfo.NominalType,
285+
itemSerializationInfo.SerializationOptions);
286+
}
287+
}
288+
}
289+
290+
return null;
291+
}
292+
263293
private BsonSerializationInfo GetSerializationInfoMember(IBsonSerializer serializer, MemberExpression memberExpression)
264294
{
265295
var declaringType = memberExpression.Expression.Type;

DriverUnitTests/DriverUnitTests.csproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@
5151
<WarningLevel>4</WarningLevel>
5252
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
5353
</PropertyGroup>
54+
<PropertyGroup>
55+
<SignAssembly>false</SignAssembly>
56+
</PropertyGroup>
57+
<PropertyGroup>
58+
<AssemblyOriginatorKeyFile>TemporaryKeyPair.snk</AssemblyOriginatorKeyFile>
59+
</PropertyGroup>
5460
<ItemGroup>
5561
<Reference Include="System" />
5662
<Reference Include="System.configuration" />
@@ -168,6 +174,7 @@
168174
<Compile Include="Linq\SelectQueryTests.cs" />
169175
<Compile Include="Linq\MongoQueryableTests.cs" />
170176
<Compile Include="Linq\MongoQueryProviderTests.cs" />
177+
<Compile Include="Linq\Utils\BsonSerializationInfoHelperTests.cs" />
171178
<Compile Include="Properties\AssemblyInfo.cs" />
172179
<Compile Include="Samples\MagicDiscriminatorTests.cs" />
173180
</ItemGroup>
@@ -198,6 +205,9 @@
198205
<Install>true</Install>
199206
</BootstrapperPackage>
200207
</ItemGroup>
208+
<ItemGroup>
209+
<None Include="TemporaryKeyPair.snk" />
210+
</ItemGroup>
201211
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
202212
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
203213
Other similar extension points exist, see Microsoft.Common.targets.
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
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+
using MongoDB.Driver.Linq.Utils;
22+
using System.Linq.Expressions;
23+
using MongoDB.Driver.Builders;
24+
using MongoDB.Bson.Serialization.Attributes;
25+
26+
namespace MongoDB.DriverUnitTests.Linq.Utils
27+
{
28+
[TestFixture]
29+
public class BsonSerializationInfoHelperTests
30+
{
31+
private class Test
32+
{
33+
[BsonElement("p")]
34+
public int Primitive { get; set; }
35+
36+
[BsonElement("c")]
37+
public Test2 Complex { get; set; }
38+
39+
[BsonElement("pe")]
40+
public List<int> PrimitiveEnumerable { get; set; }
41+
42+
[BsonElement("ce")]
43+
public List<Test2> ComplexEnumerable { get; set; }
44+
}
45+
46+
private class Test2
47+
{
48+
[BsonElement("p")]
49+
public int Primitive { get; set; }
50+
51+
[BsonElement("c")]
52+
public Test3 Complex { get; set; }
53+
54+
[BsonElement("pe")]
55+
public List<int> PrimitiveEnumerable { get; set; }
56+
57+
[BsonElement("ce")]
58+
public List<Test3> ComplexEnumerable { get; set; }
59+
}
60+
61+
private class Test3
62+
{
63+
[BsonElement("p")]
64+
public int Primitive { get; set; }
65+
}
66+
67+
[Test]
68+
public void TestPrimitiveMember()
69+
{
70+
var query = Query.Build<Test>(qb => qb.EQ(t => t.Primitive, 1));
71+
72+
Assert.AreEqual("{ \"p\" : 1 }", query.ToString());
73+
}
74+
75+
[Test]
76+
public void TestComplexMember()
77+
{
78+
var query = Query.Build<Test>(qb => qb.EQ(t => t.Complex, null));
79+
80+
Assert.AreEqual("{ \"c\" : null }", query.ToString());
81+
}
82+
83+
[Test]
84+
public void TestComplexMemberMember()
85+
{
86+
var query = Query.Build<Test>(qb => qb.EQ(t => t.Complex.Primitive, 1));
87+
88+
Assert.AreEqual("{ \"c.p\" : 1 }", query.ToString());
89+
}
90+
91+
[Test]
92+
public void TestComplexMemberComplex()
93+
{
94+
var query = Query.Build<Test>(qb => qb.EQ(t => t.Complex.Complex, null));
95+
96+
Assert.AreEqual("{ \"c.c\" : null }", query.ToString());
97+
}
98+
99+
[Test]
100+
public void TestComplexMemberComplexMember()
101+
{
102+
var query = Query.Build<Test>(qb => qb.EQ(t => t.Complex.Complex.Primitive, 1));
103+
104+
Assert.AreEqual("{ \"c.c.p\" : 1 }", query.ToString());
105+
}
106+
107+
[Test]
108+
public void TestPrimitiveEnumerable()
109+
{
110+
var query = Query.Build<Test>(qb => qb.EQ(t => t.PrimitiveEnumerable, null));
111+
112+
Assert.AreEqual("{ \"pe\" : null }", query.ToString());
113+
}
114+
115+
[Test]
116+
public void TestComplexEnumerable()
117+
{
118+
var query = Query.Build<Test>(qb => qb.EQ(t => t.ComplexEnumerable, null));
119+
120+
Assert.AreEqual("{ \"ce\" : null }", query.ToString());
121+
}
122+
123+
[Test]
124+
public void TestPrimitiveIndex()
125+
{
126+
var query = Query.Build<Test>(qb => qb.EQ(t => t.PrimitiveEnumerable[0], 1));
127+
128+
Assert.AreEqual("{ \"pe.0\" : 1 }", query.ToString());
129+
}
130+
131+
[Test]
132+
public void TestComplexIndex()
133+
{
134+
var query = Query.Build<Test>(qb => qb.EQ(t => t.ComplexEnumerable[1], null));
135+
136+
Assert.AreEqual("{ \"ce.1\" : null }", query.ToString());
137+
}
138+
139+
[Test]
140+
public void TestComplexIndexMember()
141+
{
142+
var query = Query.Build<Test>(qb => qb.EQ(t => t.ComplexEnumerable[1].Primitive, 2));
143+
144+
Assert.AreEqual("{ \"ce.1.p\" : 2 }", query.ToString());
145+
}
146+
147+
[Test]
148+
public void TestPrimitiveElementAt()
149+
{
150+
var query = Query.Build<Test>(qb => qb.EQ(t => t.PrimitiveEnumerable.ElementAt(0), 1));
151+
152+
Assert.AreEqual("{ \"pe.0\" : 1 }", query.ToString());
153+
}
154+
155+
[Test]
156+
public void TestComplexElementAt()
157+
{
158+
var query = Query.Build<Test>(qb => qb.EQ(t => t.ComplexEnumerable.ElementAt(0), null));
159+
160+
Assert.AreEqual("{ \"ce.0\" : null }", query.ToString());
161+
}
162+
163+
[Test]
164+
public void TestComplexElementAtMember()
165+
{
166+
var query = Query.Build<Test>(qb => qb.EQ(t => t.ComplexEnumerable.ElementAt(0).Primitive, 1));
167+
168+
Assert.AreEqual("{ \"ce.0.p\" : 1 }", query.ToString());
169+
}
170+
171+
172+
}
173+
}

0 commit comments

Comments
 (0)