Permalink
Browse files

Using p.S.Count() == n in a LINQ query where p.S is of type string wa…

…s erroneously mapping to an array length query. Now it is treated as an alternative for p.S.Length == n.
  • Loading branch information...
1 parent 4e5322b commit 28c9bf0a4a793fcf1364cb47c5b59a9abda0e58c rstam committed Apr 10, 2012
Showing with 59 additions and 37 deletions.
  1. +36 −37 Driver/Linq/Translators/SelectQuery.cs
  2. +23 −0 DriverUnitTests/Linq/SelectQueryTests.cs
@@ -19,6 +19,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Linq.Expressions;
+using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
@@ -249,49 +250,40 @@ private IMongoQuery BuildArrayLengthQuery(Expression variableExpression, Express
{
return null;
}
+ var value = ToInt32(constantExpression);
BsonSerializationInfo serializationInfo = null;
- var value = ToInt32(constantExpression);
var unaryExpression = variableExpression as UnaryExpression;
- if (unaryExpression != null)
+ if (unaryExpression != null && unaryExpression.NodeType == ExpressionType.ArrayLength)
{
- if (unaryExpression.NodeType == ExpressionType.ArrayLength)
+ var arrayMemberExpression = unaryExpression.Operand as MemberExpression;
+ if (arrayMemberExpression != null)
{
- var memberExpression = unaryExpression.Operand as MemberExpression;
- if (memberExpression != null)
- {
- serializationInfo = GetSerializationInfo(memberExpression);
- }
+ serializationInfo = GetSerializationInfo(arrayMemberExpression);
}
}
- var countPropertyExpression = variableExpression as MemberExpression;
- if (countPropertyExpression != null)
+ var memberExpression = variableExpression as MemberExpression;
+ if (memberExpression != null && memberExpression.Member.Name == "Count")
{
- if (countPropertyExpression.Member.Name == "Count")
+ var arrayMemberExpression = memberExpression.Expression as MemberExpression;
+ if (arrayMemberExpression != null)
{
- var memberExpression = countPropertyExpression.Expression as MemberExpression;
- if (memberExpression != null)
- {
- serializationInfo = GetSerializationInfo(memberExpression);
- }
+ serializationInfo = GetSerializationInfo(arrayMemberExpression);
}
}
- var countMethodCallExpression = variableExpression as MethodCallExpression;
- if (countMethodCallExpression != null)
+ var methodCallExpression = variableExpression as MethodCallExpression;
+ if (methodCallExpression != null && methodCallExpression.Method.Name == "Count" && methodCallExpression.Method.DeclaringType == typeof(Enumerable))
{
- if (countMethodCallExpression.Method.Name == "Count")
+ var arguments = methodCallExpression.Arguments.ToArray();
+ if (arguments.Length == 1)
{
- var arguments = countMethodCallExpression.Arguments.ToArray();
- if (arguments.Length == 1)
+ var arrayMemberExpression = methodCallExpression.Arguments[0] as MemberExpression;
+ if (arrayMemberExpression != null && arrayMemberExpression.Type != typeof(string))
{
- var memberExpression = countMethodCallExpression.Arguments[0] as MemberExpression;
- if (memberExpression != null)
- {
- serializationInfo = GetSerializationInfo(memberExpression);
- }
+ serializationInfo = GetSerializationInfo(arrayMemberExpression);
}
}
}
@@ -756,23 +748,30 @@ private IMongoQuery BuildStringLengthQuery(Expression variableExpression, Expres
{
return null;
}
+ var value = ToInt32(constantExpression);
BsonSerializationInfo serializationInfo = null;
- var value = ToInt32(constantExpression);
- var lengthPropertyExpression = variableExpression as MemberExpression;
- if (lengthPropertyExpression != null)
+ var memberExpression = variableExpression as MemberExpression;
+ if (memberExpression != null && memberExpression.Member.Name == "Length")
{
- if (lengthPropertyExpression.Member.Name == "Length")
+ var stringMemberExpression = memberExpression.Expression as MemberExpression;
+ if (stringMemberExpression != null && stringMemberExpression.Type == typeof(string))
{
- var memberExpression = lengthPropertyExpression.Expression as MemberExpression;
- if (memberExpression != null)
+ serializationInfo = GetSerializationInfo(stringMemberExpression);
+ }
+ }
+
+ var methodCallExpression = variableExpression as MethodCallExpression;
+ if (methodCallExpression != null && methodCallExpression.Method.Name == "Count" && methodCallExpression.Method.DeclaringType == typeof(Enumerable))
+ {
+ var args = methodCallExpression.Arguments.ToArray();
+ if (args.Length == 1)
+ {
+ var stringMemberExpression = args[0] as MemberExpression;
+ if (stringMemberExpression != null && stringMemberExpression.Type == typeof(string))
{
- serializationInfo = GetSerializationInfo(memberExpression);
- if (serializationInfo != null && serializationInfo.NominalType != typeof(string))
- {
- serializationInfo = null;
- }
+ serializationInfo = GetSerializationInfo(stringMemberExpression);
}
}
}
@@ -4283,6 +4283,29 @@ where c.S.Contains(".")
}
[Test]
+ public void TestWhereSCountEquals3()
+ {
+ var query = from c in _collection.AsQueryable<C>()
+ where c.S.Count() == 3
+ select c;
+
+ var translatedQuery = MongoQueryTranslator.Translate(query);
+ Assert.IsInstanceOf<SelectQuery>(translatedQuery);
+ Assert.AreSame(_collection, translatedQuery.Collection);
+ Assert.AreSame(typeof(C), translatedQuery.DocumentType);
+
+ var selectQuery = (SelectQuery)translatedQuery;
+ Assert.AreEqual("(C c) => (Enumerable.Count<Char>(c.S) == 3)", ExpressionFormatter.ToString(selectQuery.Where));
+ Assert.IsNull(selectQuery.OrderBy);
+ Assert.IsNull(selectQuery.Projection);
+ Assert.IsNull(selectQuery.Skip);
+ Assert.IsNull(selectQuery.Take);
+
+ Assert.AreEqual("{ \"s\" : /^.{3}$/s }", selectQuery.BuildQuery().ToJson());
+ Assert.AreEqual(1, Consume(query));
+ }
+
+ [Test]
public void TestWhereSEndsWithAbc()
{
var query = from c in _collection.AsQueryable<C>()

0 comments on commit 28c9bf0

Please sign in to comment.