Skip to content

Commit 63af93b

Browse files
author
rstam
committed
Fixed CSHARP-419 and CSHARP-420 (they were duplicates of each other). A LINQ query consisting of AsQueryable<T> and nothing else now works.
1 parent 89db3dd commit 63af93b

File tree

3 files changed

+111
-80
lines changed

3 files changed

+111
-80
lines changed

Driver/Linq/Translators/MongoQueryTranslator.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,27 +57,28 @@ public static TranslatedQuery Translate(MongoQueryProvider provider, Expression
5757
private static Type GetDocumentType(Expression expression)
5858
{
5959
// look for the innermost nested constant of type MongoQueryable<T> and return typeof(T)
60-
var methodCallExpression = expression as MethodCallExpression;
61-
if (methodCallExpression != null)
60+
var constantExpression = expression as ConstantExpression;
61+
if (constantExpression != null)
6262
{
63-
var firstArgument = methodCallExpression.Arguments[0];
64-
var constantExpression = firstArgument as ConstantExpression;
65-
if (constantExpression != null)
63+
var constantType = constantExpression.Type;
64+
if (constantType.IsGenericType)
6665
{
67-
var constantType = constantExpression.Type;
68-
if (constantType.IsGenericType)
66+
var genericTypeDefinition = constantType.GetGenericTypeDefinition();
67+
if (genericTypeDefinition == typeof(MongoQueryable<>))
6968
{
70-
var genericTypeDefinition = constantType.GetGenericTypeDefinition();
71-
if (genericTypeDefinition == typeof(MongoQueryable<>))
72-
{
73-
return constantType.GetGenericArguments()[0];
74-
}
69+
return constantType.GetGenericArguments()[0];
7570
}
7671
}
77-
return GetDocumentType(firstArgument);
7872
}
7973

80-
throw new ArgumentOutOfRangeException("Unable to find root IQueryable");
74+
var methodCallExpression = expression as MethodCallExpression;
75+
if (methodCallExpression != null && methodCallExpression.Arguments.Count != 0)
76+
{
77+
return GetDocumentType(methodCallExpression.Arguments[0]);
78+
}
79+
80+
var message = string.Format("Unable to find document type of expression: {0}.", ExpressionFormatter.ToString(expression));
81+
throw new ArgumentOutOfRangeException(message);
8182
}
8283
}
8384
}

Driver/Linq/Translators/SelectQuery.cs

Lines changed: 80 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -189,78 +189,24 @@ public override object Execute()
189189
/// <param name="expression">The LINQ query expression tree.</param>
190190
public void Translate(Expression expression)
191191
{
192-
var methodCallExpression = expression as MethodCallExpression;
193-
if (methodCallExpression == null)
192+
// when we reach the original MongoQueryable<TDocument> we're done
193+
var constantExpression = expression as ConstantExpression;
194+
if (constantExpression != null)
194195
{
195-
throw new ArgumentOutOfRangeException("expression");
196+
if (constantExpression.Type == typeof(MongoQueryable<>).MakeGenericType(DocumentType))
197+
{
198+
return;
199+
}
196200
}
197201

198-
if (methodCallExpression.Arguments.Count == 0)
202+
var methodCallExpression = expression as MethodCallExpression;
203+
if (methodCallExpression != null)
199204
{
200-
throw new ArgumentOutOfRangeException("expression");
205+
TranslateMethodCall(methodCallExpression);
206+
return;
201207
}
202208

203-
var source = methodCallExpression.Arguments[0];
204-
if (source is MethodCallExpression)
205-
{
206-
Translate(source);
207-
}
208-
209-
var methodName = methodCallExpression.Method.Name;
210-
switch (methodName)
211-
{
212-
case "Any":
213-
TranslateAny(methodCallExpression);
214-
break;
215-
case "Count":
216-
case "LongCount":
217-
TranslateCount(methodCallExpression);
218-
break;
219-
case "Distinct":
220-
TranslateDistinct(methodCallExpression);
221-
break;
222-
case "ElementAt":
223-
case "ElementAtOrDefault":
224-
TranslateElementAt(methodCallExpression);
225-
break;
226-
case "First":
227-
case "FirstOrDefault":
228-
case "Single":
229-
case "SingleOrDefault":
230-
TranslateFirstOrSingle(methodCallExpression);
231-
break;
232-
case "Last":
233-
case "LastOrDefault":
234-
TranslateLast(methodCallExpression);
235-
break;
236-
case "Max":
237-
case "Min":
238-
TranslateMaxMin(methodCallExpression);
239-
break;
240-
case "OrderBy":
241-
case "OrderByDescending":
242-
TranslateOrderBy(methodCallExpression);
243-
break;
244-
case "Select":
245-
TranslateSelect(methodCallExpression);
246-
break;
247-
case "Skip":
248-
TranslateSkip(methodCallExpression);
249-
break;
250-
case "Take":
251-
TranslateTake(methodCallExpression);
252-
break;
253-
case "ThenBy":
254-
case "ThenByDescending":
255-
TranslateThenBy(methodCallExpression);
256-
break;
257-
case "Where":
258-
TranslateWhere(methodCallExpression);
259-
break;
260-
default:
261-
var message = string.Format("The {0} query operator is not supported.", methodName);
262-
throw new NotSupportedException(message);
263-
}
209+
var message = string.Format("Don't know how to translate expression: {0}.", ExpressionFormatter.ToString(expression));
264210
}
265211

266212
// private methods
@@ -1283,6 +1229,74 @@ private void TranslateMaxMin(MethodCallExpression methodCallExpression)
12831229
SetElementSelector(methodCallExpression, source => source.Cast<object>().First());
12841230
}
12851231

1232+
private void TranslateMethodCall(MethodCallExpression methodCallExpression)
1233+
{
1234+
if (methodCallExpression.Arguments.Count == 0)
1235+
{
1236+
var message = string.Format("Method call expression has no arguments: {0}.", ExpressionFormatter.ToString(methodCallExpression));
1237+
throw new ArgumentOutOfRangeException(message);
1238+
}
1239+
1240+
var source = methodCallExpression.Arguments[0];
1241+
Translate(source);
1242+
1243+
var methodName = methodCallExpression.Method.Name;
1244+
switch (methodName)
1245+
{
1246+
case "Any":
1247+
TranslateAny(methodCallExpression);
1248+
break;
1249+
case "Count":
1250+
case "LongCount":
1251+
TranslateCount(methodCallExpression);
1252+
break;
1253+
case "Distinct":
1254+
TranslateDistinct(methodCallExpression);
1255+
break;
1256+
case "ElementAt":
1257+
case "ElementAtOrDefault":
1258+
TranslateElementAt(methodCallExpression);
1259+
break;
1260+
case "First":
1261+
case "FirstOrDefault":
1262+
case "Single":
1263+
case "SingleOrDefault":
1264+
TranslateFirstOrSingle(methodCallExpression);
1265+
break;
1266+
case "Last":
1267+
case "LastOrDefault":
1268+
TranslateLast(methodCallExpression);
1269+
break;
1270+
case "Max":
1271+
case "Min":
1272+
TranslateMaxMin(methodCallExpression);
1273+
break;
1274+
case "OrderBy":
1275+
case "OrderByDescending":
1276+
TranslateOrderBy(methodCallExpression);
1277+
break;
1278+
case "Select":
1279+
TranslateSelect(methodCallExpression);
1280+
break;
1281+
case "Skip":
1282+
TranslateSkip(methodCallExpression);
1283+
break;
1284+
case "Take":
1285+
TranslateTake(methodCallExpression);
1286+
break;
1287+
case "ThenBy":
1288+
case "ThenByDescending":
1289+
TranslateThenBy(methodCallExpression);
1290+
break;
1291+
case "Where":
1292+
TranslateWhere(methodCallExpression);
1293+
break;
1294+
default:
1295+
var message = string.Format("The {0} query operator is not supported.", methodName);
1296+
throw new NotSupportedException(message);
1297+
}
1298+
}
1299+
12861300
private void TranslateOrderBy(MethodCallExpression methodCallExpression)
12871301
{
12881302
if (methodCallExpression.Arguments.Count != 2)

DriverOnlineTests/Linq/SelectQueryTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,14 @@ public void TestAnyWithPredicateTrue()
242242
Assert.IsTrue(result);
243243
}
244244

245+
[Test]
246+
public void TestAsQueryableWithNothingElse()
247+
{
248+
var query = _collection.AsQueryable<C>();
249+
var result = query.ToList();
250+
Assert.AreEqual(5, result.Count);
251+
}
252+
245253
[Test]
246254
[ExpectedException(typeof(NotSupportedException), ExpectedMessage = "The Average query operator is not supported.")]
247255
public void TestAverage()
@@ -1599,6 +1607,14 @@ public void TestSelectWithIndex()
15991607
query.ToList(); // execute query
16001608
}
16011609

1610+
[Test]
1611+
public void TestSelectWithNothingElse()
1612+
{
1613+
var query = from c in _collection.AsQueryable<C>() select c;
1614+
var result = query.ToList();
1615+
Assert.AreEqual(5, result.Count);
1616+
}
1617+
16021618
[Test]
16031619
[ExpectedException(typeof(NotSupportedException), ExpectedMessage = "The SequenceEqual query operator is not supported.")]
16041620
public void TestSequenceEqual()

0 commit comments

Comments
 (0)