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

Commit 37f27d5

Browse files
authored
Merge pull request #1 from ServiceStack/master
Update from upstream (my changes)
2 parents c6fe8aa + aaf66c1 commit 37f27d5

File tree

10 files changed

+72
-28
lines changed

10 files changed

+72
-28
lines changed

lib/ServiceStack.Client.dll

0 Bytes
Binary file not shown.

lib/ServiceStack.Common.dll

512 Bytes
Binary file not shown.

lib/ServiceStack.Interfaces.dll

0 Bytes
Binary file not shown.

lib/ServiceStack.Text.dll

1.5 KB
Binary file not shown.

lib/ServiceStack.Text.pdb

4 KB
Binary file not shown.

lib/signed/ServiceStack.Text.dll

0 Bytes
Binary file not shown.

src/ServiceStack.OrmLite/Expressions/SqlExpression.Join.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace ServiceStack.OrmLite
99
{
1010
public abstract partial class SqlExpression<T> : ISqlExpression
1111
{
12-
List<ModelDefinition> tableDefs = new List<ModelDefinition>();
12+
protected List<ModelDefinition> tableDefs = new List<ModelDefinition>();
1313

1414
public bool IsJoinedTable(Type type)
1515
{

src/ServiceStack.OrmLite/Expressions/SqlExpression.cs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public abstract partial class SqlExpression<T> : ISqlExpression, IHasUntypedSqlE
3737
protected bool useFieldName = false;
3838
protected bool selectDistinct = false;
3939
protected bool CustomSelect { get; set; }
40-
private ModelDefinition modelDef;
40+
protected ModelDefinition modelDef;
4141
public bool PrefixFieldWithTableName { get; set; }
4242
public bool WhereStatementWithoutWhereString { get; set; }
4343
public IOrmLiteDialectProvider DialectProvider { get; set; }
@@ -1238,12 +1238,12 @@ protected virtual object VisitBinary(BinaryExpression b)
12381238
var operand = BindOperant(b.NodeType); //sep= " " ??
12391239
if (operand == "AND" || operand == "OR")
12401240
{
1241-
if (IsNeedCompareToTrue(b.Left))
1241+
if (IsBooleanComparison(b.Left))
12421242
left = new PartialSqlString(string.Format("{0}={1}", VisitMemberAccess((MemberExpression) b.Left), GetQuotedTrueValue()));
12431243
else
12441244
left = Visit(b.Left);
12451245

1246-
if (IsNeedCompareToTrue(b.Right))
1246+
if (IsBooleanComparison(b.Right))
12471247
right = new PartialSqlString(string.Format("{0}={1}", VisitMemberAccess((MemberExpression) b.Right), GetQuotedTrueValue()));
12481248
else
12491249
right = Visit(b.Right);
@@ -1354,17 +1354,16 @@ protected virtual object VisitBinary(BinaryExpression b)
13541354
/// <summary>
13551355
/// Determines whether the expression is the parameter inside MemberExpression which should be compared with TrueExpression.
13561356
/// </summary>
1357-
/// <param name="e">The specified expression.</param>
13581357
/// <returns>Returns true if the specified expression is the parameter inside MemberExpression which should be compared with TrueExpression;
13591358
/// otherwise, false.</returns>
1360-
protected virtual bool IsNeedCompareToTrue(Expression e)
1359+
protected virtual bool IsBooleanComparison(Expression e)
13611360
{
13621361
if (!(e is MemberExpression)) return false;
13631362

13641363
var m = (MemberExpression)e;
13651364

13661365
if (m.Member.DeclaringType.IsNullableType() &&
1367-
m.Member.Name == "HasValue") //nameof(Nullable<bool>.HasValue))
1366+
m.Member.Name == "HasValue") //nameof(Nullable<bool>.HasValue)
13681367
return false;
13691368

13701369
return IsParameterAccess(m);
@@ -1373,7 +1372,6 @@ protected virtual bool IsNeedCompareToTrue(Expression e)
13731372
/// <summary>
13741373
/// Determines whether the expression is the parameter.
13751374
/// </summary>
1376-
/// <param name="e">The specified expression.</param>
13771375
/// <returns>Returns true if the specified expression is parameter;
13781376
/// otherwise, false.</returns>
13791377
protected virtual bool IsParameterAccess(Expression e)
@@ -1382,9 +1380,8 @@ protected virtual bool IsParameterAccess(Expression e)
13821380
}
13831381

13841382
/// <summary>
1385-
/// Determines whether the expression is the parameter or convert.
1383+
/// Determines whether the expression is a Parameter or Convert Expression.
13861384
/// </summary>
1387-
/// <param name="e">The specified expression.</param>
13881385
/// <returns>Returns true if the specified expression is parameter or convert;
13891386
/// otherwise, false.</returns>
13901387
protected virtual bool IsParameterOrConvertAccess(Expression e)
@@ -1398,38 +1395,42 @@ protected bool CheckExpressionForTypes(Expression e, ExpressionType[] types)
13981395
{
13991396
if (types.Contains(e.NodeType))
14001397
{
1401-
var isSubExprAccess = e is UnaryExpression &&
1402-
((UnaryExpression)e).Operand is IndexExpression;
1398+
var subUnaryExpr = e as UnaryExpression;
1399+
var isSubExprAccess = subUnaryExpr != null && subUnaryExpr.Operand is IndexExpression;
14031400

14041401
if (!isSubExprAccess)
14051402
return true;
14061403
}
14071404

1408-
if (e is BinaryExpression)
1405+
var binaryExpr = e as BinaryExpression;
1406+
if (binaryExpr != null)
14091407
{
1410-
if (CheckExpressionForTypes(((BinaryExpression)e).Left, types))
1408+
if (CheckExpressionForTypes(binaryExpr.Left, types))
14111409
return true;
14121410

1413-
if (CheckExpressionForTypes(((BinaryExpression)e).Right, types))
1411+
if (CheckExpressionForTypes(binaryExpr.Right, types))
14141412
return true;
14151413
}
14161414

1417-
if (e is MethodCallExpression)
1415+
var methodCallExpr = e as MethodCallExpression;
1416+
if (methodCallExpr != null)
14181417
{
1419-
for (int i = 0; i < ((MethodCallExpression)e).Arguments.Count; i++)
1418+
for (var i = 0; i < methodCallExpr.Arguments.Count; i++)
14201419
{
1421-
if (CheckExpressionForTypes(((MethodCallExpression)e).Arguments[0], types))
1420+
if (CheckExpressionForTypes(methodCallExpr.Arguments[0], types))
14221421
return true;
14231422
}
14241423
}
14251424

1426-
if (e is UnaryExpression)
1425+
var unaryExpr = e as UnaryExpression;
1426+
if (unaryExpr != null)
14271427
{
1428-
if (CheckExpressionForTypes(((UnaryExpression)e).Operand, types))
1428+
if (CheckExpressionForTypes(unaryExpr.Operand, types))
14291429
return true;
14301430
}
14311431

1432-
e = e is MemberExpression ? ((MemberExpression)e).Expression : null;
1432+
var memberExpr = e as MemberExpression;
1433+
e = memberExpr != null ? memberExpr.Expression : null;
14331434
}
14341435

14351436
return false;
@@ -1834,7 +1835,7 @@ protected string RemoveQuoteFromAlias(string exp)
18341835
return exp;
18351836
}
18361837

1837-
protected bool IsFieldName(object quotedExp)
1838+
protected virtual bool IsFieldName(object quotedExp)
18381839
{
18391840
var fieldExpr = quotedExp.ToString().StripTablePrefixes();
18401841
var unquotedExpr = fieldExpr.StripQuotes();

tests/ServiceStack.OrmLite.Tests/ExpressionVisitorTests.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
using System.Linq;
55
using NUnit.Framework;
66
using ServiceStack.DataAnnotations;
7+
using ServiceStack.Logging;
8+
using ServiceStack.Text;
79

810
namespace ServiceStack.OrmLite.Tests
911
{
@@ -363,20 +365,20 @@ public void Can_Where_using_filter_with_nested_properties()
363365
Join<TestType2>().
364366
Where(x => (!x.NullableBoolCol.HasValue || x.NullableBoolCol.Value) && x.NullableIntCol.HasValue && x.TestType2ObjCol.BoolCol);
365367
var target = Db.Select(q);
366-
Assert.AreEqual(2, target.Count);
368+
Assert.That(target.Count, Is.EqualTo(2));
367369

368370
q = Db.From<TestType>().
369371
Join<TestType2>().
370372
Where(x => x.TestType2ObjCol.BoolCol && x.DateCol != DateTime.MinValue);
371373
target = Db.Select(q);
372-
Assert.AreEqual(2, target.Count);
374+
Assert.That(target.Count, Is.EqualTo(2));
373375

374376
q = Db.From<TestType>().
375377
Join<TestType2>().
376378
Where(x => x.TestType2ObjCol.BoolCol && x.TestType2ObjCol.BoolCol == nullableTrue &&
377379
x.DateCol != DateTime.MinValue && x.TestType2ObjCol.TestType2Name == filterText2);
378380
target = Db.Select(q);
379-
Assert.AreEqual(1, target.Count);
381+
Assert.That(target.Count, Is.EqualTo(1));
380382

381383
var intValue = 300;
382384
q = Db.From<TestType>().
@@ -386,7 +388,7 @@ public void Can_Where_using_filter_with_nested_properties()
386388
x.TestType2ObjCol.TestType3ObjCol.TestType3Name == filterText3 &&
387389
x.TestType2ObjCol.TestType3ObjCol.CustomInt == new CustomInt(intValue));
388390
target = Db.Select(q);
389-
Assert.AreEqual(1, target.Count);
391+
Assert.That(target.Count, Is.EqualTo(1));
390392

391393
q = Db.From<TestType>().
392394
Join<TestType2>().
@@ -397,7 +399,7 @@ public void Can_Where_using_filter_with_nested_properties()
397399
Having(x => (Sql.Max(x.TestType2ObjCol.TestType3ObjCol.CustomInt) ?? 0) == new CustomInt(100)).
398400
Select(x => x.TestType2ObjCol.TestType3ObjCol.CustomInt);
399401
target = Db.Select(q);
400-
Assert.AreEqual(1, target.Count);
402+
Assert.That(target.Count, Is.EqualTo(1));
401403

402404
q = Db.From<TestType>().
403405
Join<TestType2>().
@@ -408,7 +410,7 @@ public void Can_Where_using_filter_with_nested_properties()
408410
Having(x => (Sql.Max(x.TestType2ObjCol.TestType3ObjCol.CustomInt) ?? 0) != 10).
409411
Select(x => x.TestType2ObjCol.TestType3ObjCol.CustomInt);
410412
target = Db.Select(q);
411-
Assert.AreEqual(1, target.Count);
413+
Assert.That(target.Count, Is.EqualTo(1));
412414
}
413415

414416
private int MethodReturningInt(int val)

tests/ServiceStack.OrmLite.Tests/Issues/SqlExpressionSubSqlExpressionIssue.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System;
22
using System.Data;
33
using System.Linq;
4+
using System.Linq.Expressions;
45
using NUnit.Framework;
56
using ServiceStack.DataAnnotations;
67
using ServiceStack.Logging;
8+
using ServiceStack.OrmLite.SqlServer;
79
using ServiceStack.Text;
810

911
namespace ServiceStack.OrmLite.Tests.Issues
@@ -238,6 +240,45 @@ public void SubExpressions_TestMethod3()
238240
w.TestMethod3();
239241
}
240242
}
243+
244+
[Test]
245+
public void SubExpressions_with_CustomSqlExpression_and_merging_multiple_predicates()
246+
{
247+
var db = new OrmLiteConnection(new OrmLiteConnectionFactory("test", new CustomSqlServerDialectProvider()));
248+
249+
var q = db.From<MarginItem>().Where(s => Sql.In(s.Identity,
250+
db.From<WaybillItem>()
251+
.Where(w => Sql.In(w.WaybillId,
252+
db.From<Waybill>()
253+
.Where(bb => bb.Identity == null)
254+
.And(bb => bb.Name == "test")
255+
.Select(ww => ww.Identity))
256+
)
257+
.Select(b => b.MarginItemId)));
258+
259+
Assert.That(q.ToSelectStatement().NormalizeSql(), Is.StringContaining("@"));
260+
}
261+
}
262+
263+
class CustomSqlExpression<T> : SqlServerExpression<T>
264+
{
265+
private Expression<Func<T, bool>> _whereExpression;
266+
267+
public CustomSqlExpression(IOrmLiteDialectProvider dialectProvider) : base(dialectProvider) {}
268+
269+
public override SqlExpression<T> And(Expression<Func<T, bool>> predicate)
270+
{
271+
_whereExpression = _whereExpression == null ? predicate : predicate.And(_whereExpression);
272+
return base.And(predicate);
273+
}
274+
}
275+
276+
class CustomSqlServerDialectProvider : SqlServerOrmLiteDialectProvider
277+
{
278+
public override SqlExpression<T> SqlExpression<T>()
279+
{
280+
return new CustomSqlExpression<T>(this);
281+
}
241282
}
242283

243284
public class WaybillItem : BaseObject

0 commit comments

Comments
 (0)