Merge pull request #1167 from umbraco/temp-U4-8154
U4-8154 - bugfix Sql query expressions parsing
This commit is contained in:
@@ -128,6 +128,34 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
right = Visit(b.Right);
|
||||
}
|
||||
}
|
||||
else if (operand == "=")
|
||||
{
|
||||
// deal with (x == true|false) - most common
|
||||
var constRight = b.Right as ConstantExpression;
|
||||
if (constRight != null && constRight.Type == typeof (bool))
|
||||
return ((bool) constRight.Value) ? VisitNotNot(b.Left) : VisitNot(b.Left);
|
||||
right = Visit(b.Right);
|
||||
|
||||
// deal with (true|false == x) - why not
|
||||
var constLeft = b.Left as ConstantExpression;
|
||||
if (constLeft != null && constLeft.Type == typeof (bool))
|
||||
return ((bool) constLeft.Value) ? VisitNotNot(b.Right) : VisitNot(b.Right);
|
||||
left = Visit(b.Left);
|
||||
}
|
||||
else if (operand == "<>")
|
||||
{
|
||||
// deal with (x != true|false) - most common
|
||||
var constRight = b.Right as ConstantExpression;
|
||||
if (constRight != null && constRight.Type == typeof(bool))
|
||||
return ((bool) constRight.Value) ? VisitNot(b.Left) : VisitNotNot(b.Left);
|
||||
right = Visit(b.Right);
|
||||
|
||||
// deal with (true|false != x) - why not
|
||||
var constLeft = b.Left as ConstantExpression;
|
||||
if (constLeft != null && constLeft.Type == typeof(bool))
|
||||
return ((bool) constLeft.Value) ? VisitNot(b.Right) : VisitNotNot(b.Right);
|
||||
left = Visit(b.Left);
|
||||
}
|
||||
else
|
||||
{
|
||||
left = Visit(b.Left);
|
||||
@@ -231,25 +259,47 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
switch (u.NodeType)
|
||||
{
|
||||
case ExpressionType.Not:
|
||||
var o = Visit(u.Operand);
|
||||
|
||||
//use a Not equal operator instead of <> since we don't know that <> works in all sql servers
|
||||
|
||||
switch (u.Operand.NodeType)
|
||||
{
|
||||
case ExpressionType.MemberAccess:
|
||||
//In this case it wil be a false property , i.e. x => !Trashed
|
||||
SqlParameters.Add(true);
|
||||
return string.Format("NOT ({0} = @0)", o);
|
||||
default:
|
||||
//In this case it could be anything else, such as: x => !x.Path.StartsWith("-20")
|
||||
return string.Format("NOT ({0})", o);
|
||||
}
|
||||
return VisitNot(u.Operand);
|
||||
default:
|
||||
return Visit(u.Operand);
|
||||
}
|
||||
}
|
||||
|
||||
private string VisitNot(Expression exp)
|
||||
{
|
||||
var o = Visit(exp);
|
||||
|
||||
// use a "NOT (...)" syntax instead of "<>" since we don't know whether "<>" works in all sql servers
|
||||
// also, x.StartsWith(...) translates to "x LIKE '...%'" which we cannot "<>" and have to "NOT (...")
|
||||
|
||||
switch (exp.NodeType)
|
||||
{
|
||||
case ExpressionType.MemberAccess:
|
||||
// false property , i.e. x => !Trashed
|
||||
SqlParameters.Add(true);
|
||||
return "NOT (" + o + " = @0)";
|
||||
default:
|
||||
// could be anything else, such as: x => !x.Path.StartsWith("-20")
|
||||
return "NOT (" + o + ")";
|
||||
}
|
||||
}
|
||||
|
||||
private string VisitNotNot(Expression exp)
|
||||
{
|
||||
var o = Visit(exp);
|
||||
|
||||
switch (exp.NodeType)
|
||||
{
|
||||
case ExpressionType.MemberAccess:
|
||||
// true property, i.e. x => Trashed
|
||||
SqlParameters.Add(true);
|
||||
return o + " = @0";
|
||||
default:
|
||||
// could be anything else, such as: x => x.Path.StartsWith("-20")
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual string VisitNewArray(NewArrayExpression na)
|
||||
{
|
||||
|
||||
|
||||
@@ -51,6 +51,18 @@ namespace Umbraco.Tests.Persistence.Querying
|
||||
Assert.AreEqual("-20%", sql.Arguments[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_EqualsFalse_Starts_With()
|
||||
{
|
||||
var level = 1;
|
||||
var sql = new Sql("SELECT *").From<NodeDto>().Where<NodeDto>(x => x.Level == level && x.Path.StartsWith("-20") == false);
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE ([umbracoNode].[level] = @0 AND NOT (upper([umbracoNode].[path]) LIKE upper(@1)))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(2, sql.Arguments.Length);
|
||||
Assert.AreEqual(level, sql.Arguments[0]);
|
||||
Assert.AreEqual("-20%", sql.Arguments[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_Equals_Clause()
|
||||
{
|
||||
@@ -71,6 +83,16 @@ namespace Umbraco.Tests.Persistence.Querying
|
||||
Assert.AreEqual(true, sql.Arguments[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_EqualsFalse_Boolean()
|
||||
{
|
||||
var sql = new Sql("SELECT *").From<NodeDto>().Where<NodeDto>(x => x.Trashed == false);
|
||||
|
||||
Assert.AreEqual("SELECT * FROM [umbracoNode] WHERE (NOT ([umbracoNode].[trashed] = @0))", sql.SQL.Replace("\n", " "));
|
||||
Assert.AreEqual(1, sql.Arguments.Length);
|
||||
Assert.AreEqual(true, sql.Arguments[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Where_Clause_With_Boolean()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user