Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit cc3a919

Browse files
committed
Second commit: added support for visiting of virtual properties in custom SqlExpression
1 parent 20827c6 commit cc3a919

File tree

2 files changed

+62
-17
lines changed

2 files changed

+62
-17
lines changed

src/ServiceStack.OrmLite/Expressions/SqlExpression.cs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,7 @@ protected virtual object VisitBinary(BinaryExpression b)
12981298

12991299
if (!(left is PartialSqlString) && !(right is PartialSqlString))
13001300
{
1301-
var result = CachedExpressionCompiler.Evaluate(b);
1301+
var result = CachedExpressionCompiler.Evaluate(PreEvaluateBinary(b, left, right));
13021302
return result;
13031303
}
13041304

@@ -1363,19 +1363,7 @@ protected virtual object VisitBinary(BinaryExpression b)
13631363
}
13641364
else if (!(left is PartialSqlString) && !(right is PartialSqlString))
13651365
{
1366-
var visitedBinaryExp = b;
1367-
1368-
if (IsParameterAccess(b.Left) || IsParameterAccess(b.Right))
1369-
{
1370-
var eLeft = !IsParameterAccess(b.Left) ? b.Left : Expression.Constant(left, b.Left.Type);
1371-
var eRight = !IsParameterAccess(b.Right) ? b.Right : Expression.Constant(right, b.Right.Type);
1372-
if (b.NodeType == ExpressionType.Coalesce)
1373-
visitedBinaryExp = Expression.Coalesce(eLeft, eRight, b.Conversion);
1374-
else
1375-
visitedBinaryExp = Expression.MakeBinary(b.NodeType, eLeft, eRight, b.IsLiftedToNull, b.Method);
1376-
}
1377-
1378-
var evaluatedValue = CachedExpressionCompiler.Evaluate(visitedBinaryExp);
1366+
var evaluatedValue = CachedExpressionCompiler.Evaluate(PreEvaluateBinary(b, left, right));
13791367
var result = VisitConstant(Expression.Constant(evaluatedValue));
13801368
return result;
13811369
}
@@ -1414,6 +1402,23 @@ protected virtual object VisitBinary(BinaryExpression b)
14141402
}
14151403
}
14161404

1405+
private BinaryExpression PreEvaluateBinary(BinaryExpression b, object left, object right)
1406+
{
1407+
var visitedBinaryExp = b;
1408+
1409+
if (IsParameterAccess(b.Left) || IsParameterAccess(b.Right))
1410+
{
1411+
var eLeft = !IsParameterAccess(b.Left) ? b.Left : Expression.Constant(left, b.Left.Type);
1412+
var eRight = !IsParameterAccess(b.Right) ? b.Right : Expression.Constant(right, b.Right.Type);
1413+
if (b.NodeType == ExpressionType.Coalesce)
1414+
visitedBinaryExp = Expression.Coalesce(eLeft, eRight, b.Conversion);
1415+
else
1416+
visitedBinaryExp = Expression.MakeBinary(b.NodeType, eLeft, eRight, b.IsLiftedToNull, b.Method);
1417+
}
1418+
1419+
return visitedBinaryExp;
1420+
}
1421+
14171422
/// <summary>
14181423
/// Determines whether the expression is the parameter inside MemberExpression which should be compared with TrueExpression.
14191424
/// </summary>

tests/ServiceStack.OrmLite.Tests/CustomSqlExpressionTests.cs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public class Waybill
1616
public string Name { get; set; }
1717

1818
public string VirtProperty => "WaybillVirtPropertyValue";
19+
20+
public string VirtProperty2 => "WaybillVirtPropertyValue2";
1921
}
2022

2123
public class CustomSqlServerDialectProvider : SqliteOrmLiteDialectProvider
@@ -35,10 +37,12 @@ public CustomSqlExpression(IOrmLiteDialectProvider dialectProvider) : base(diale
3537

3638
protected override Object GetMemberExpression(MemberExpression m)
3739
{
38-
if (m.Member.DeclaringType == typeof(Waybill) &&
39-
m.Member.Name == nameof(Waybill.VirtProperty))
40+
if (m.Member.DeclaringType == typeof(Waybill))
4041
{
41-
return "WaybillVirtPropertyValue";
42+
if (m.Member.Name == nameof(Waybill.VirtProperty))
43+
return "WaybillVirtPropertyValue";
44+
if (m.Member.Name == nameof(Waybill.VirtProperty2))
45+
return "WaybillVirtPropertyValue2";
4246
}
4347

4448
return base.GetMemberExpression(m);
@@ -113,5 +117,41 @@ public void Can_Where_using_constant_filter4()
113117
var target = Db.Select(q);
114118
Assert.AreEqual(3, target.Count);
115119
}
120+
121+
[Test]
122+
public void Can_Where_using_constant_filter5()
123+
{
124+
System.Linq.Expressions.Expression<Func<Waybill, bool>> filter = x => x.VirtProperty == "WaybillVirtPropertyValue" || x.VirtProperty2 == "WaybillVirtPropertyValue2";
125+
var q = Db.From<Waybill>().Where(filter);
126+
var target = Db.Select(q);
127+
Assert.AreEqual(3, target.Count);
128+
}
129+
130+
[Test]
131+
public void Can_Where_using_constant_filter6()
132+
{
133+
System.Linq.Expressions.Expression<Func<Waybill, bool>> filter = x => x.VirtProperty == "WaybillVirtPropertyValue" && x.VirtProperty2 == "WaybillVirtPropertyValue2";
134+
var q = Db.From<Waybill>().Where(filter);
135+
var target = Db.Select(q);
136+
Assert.AreEqual(3, target.Count);
137+
}
138+
139+
[Test]
140+
public void Can_Where_using_constant_filter7()
141+
{
142+
System.Linq.Expressions.Expression<Func<Waybill, bool>> filter = x => x.VirtProperty == "WaybillVirtPropertyValue" || x.VirtProperty2 == "Any";
143+
var q = Db.From<Waybill>().Where(filter);
144+
var target = Db.Select(q);
145+
Assert.AreEqual(3, target.Count);
146+
}
147+
148+
[Test]
149+
public void Can_Where_using_constant_filter8()
150+
{
151+
System.Linq.Expressions.Expression<Func<Waybill, bool>> filter = x => x.VirtProperty == "WaybillVirtPropertyValue" && x.VirtProperty2 == "Any";
152+
var q = Db.From<Waybill>().Where(filter);
153+
var target = Db.Select(q);
154+
Assert.AreEqual(0, target.Count);
155+
}
116156
}
117157
}

0 commit comments

Comments
 (0)