@@ -41,7 +41,7 @@ public abstract partial class SqlExpression<T> : ISqlExpression, IHasUntypedSqlE
41
41
public bool PrefixFieldWithTableName { get ; set ; }
42
42
public bool WhereStatementWithoutWhereString { get ; set ; }
43
43
public IOrmLiteDialectProvider DialectProvider { get ; set ; }
44
- public List < IDbDataParameter > Params { get ; set ; }
44
+ public List < IDbDataParameter > Params { get ; set ; }
45
45
46
46
protected string Sep
47
47
{
@@ -107,7 +107,7 @@ public virtual SqlExpression<T> Select(string selectExpression)
107
107
{
108
108
if ( selectExpression != null )
109
109
selectExpression . SqlVerifyFragment ( ) ;
110
-
110
+
111
111
return UnsafeSelect ( selectExpression ) ;
112
112
}
113
113
@@ -590,7 +590,7 @@ private SqlExpression<T> OrderByFields(string orderBySuffix, string[] fieldNames
590
590
foreach ( var fieldName in fieldNames )
591
591
{
592
592
var reverse = fieldName . StartsWith ( "-" ) ;
593
- var useSuffix = reverse
593
+ var useSuffix = reverse
594
594
? ( orderBySuffix == OrderBySuffix . Asc ? OrderBySuffix . Desc : OrderBySuffix . Asc )
595
595
: orderBySuffix ;
596
596
var useName = reverse ? fieldName . Substring ( 1 ) : fieldName ;
@@ -980,7 +980,7 @@ public virtual void PrepareUpdateStatement(IDbCommand dbCmd, T item, bool exclud
980
980
{
981
981
if ( fieldDef . ShouldSkipUpdate ( ) ) continue ;
982
982
if ( fieldDef . IsRowVersion ) continue ;
983
- if ( UpdateFields . Count > 0
983
+ if ( UpdateFields . Count > 0
984
984
&& ! UpdateFields . Contains ( fieldDef . Name ) ) continue ; // added
985
985
986
986
var value = fieldDef . GetValue ( item ) ;
@@ -1238,17 +1238,13 @@ protected virtual object VisitBinary(BinaryExpression b)
1238
1238
var operand = BindOperant ( b . NodeType ) ; //sep= " " ??
1239
1239
if ( operand == "AND" || operand == "OR" )
1240
1240
{
1241
- var m = b . Left as MemberExpression ;
1242
- if ( m != null && m . Expression != null
1243
- && m . Expression . NodeType == ExpressionType . Parameter )
1244
- left = new PartialSqlString ( string . Format ( "{0}={1}" , VisitMemberAccess ( m ) , GetQuotedTrueValue ( ) ) ) ;
1241
+ if ( IsNeedCompareToTrue ( b . Left ) )
1242
+ left = new PartialSqlString ( string . Format ( "{0}={1}" , VisitMemberAccess ( ( MemberExpression ) b . Left ) , GetQuotedTrueValue ( ) ) ) ;
1245
1243
else
1246
1244
left = Visit ( b . Left ) ;
1247
1245
1248
- m = b . Right as MemberExpression ;
1249
- if ( m != null && m . Expression != null
1250
- && m . Expression . NodeType == ExpressionType . Parameter )
1251
- right = new PartialSqlString ( string . Format ( "{0}={1}" , VisitMemberAccess ( m ) , GetQuotedTrueValue ( ) ) ) ;
1246
+ if ( IsNeedCompareToTrue ( b . Right ) )
1247
+ right = new PartialSqlString ( string . Format ( "{0}={1}" , VisitMemberAccess ( ( MemberExpression ) b . Right ) , GetQuotedTrueValue ( ) ) ) ;
1252
1248
else
1253
1249
right = Visit ( b . Right ) ;
1254
1250
@@ -1355,6 +1351,90 @@ protected virtual object VisitBinary(BinaryExpression b)
1355
1351
}
1356
1352
}
1357
1353
1354
+ /// <summary>
1355
+ /// Determines whether the expression is the parameter inside MemberExpression which should be compared with TrueExpression.
1356
+ /// </summary>
1357
+ /// <param name="e">The specified expression.</param>
1358
+ /// <returns>Returns true if the specified expression is the parameter inside MemberExpression which should be compared with TrueExpression;
1359
+ /// otherwise, false.</returns>
1360
+ protected virtual bool IsNeedCompareToTrue ( Expression e )
1361
+ {
1362
+ if ( ! ( e is MemberExpression ) ) return false ;
1363
+
1364
+ var m = ( MemberExpression ) e ;
1365
+
1366
+ if ( m . Member . DeclaringType . IsNullableType ( ) &&
1367
+ m . Member . Name == "HasValue" ) //nameof(Nullable<bool>.HasValue))
1368
+ return false ;
1369
+
1370
+ return IsParameterAccess ( m ) ;
1371
+ }
1372
+
1373
+ /// <summary>
1374
+ /// Determines whether the expression is the parameter.
1375
+ /// </summary>
1376
+ /// <param name="e">The specified expression.</param>
1377
+ /// <returns>Returns true if the specified expression is parameter;
1378
+ /// otherwise, false.</returns>
1379
+ protected virtual bool IsParameterAccess ( Expression e )
1380
+ {
1381
+ return CheckExpressionForTypes ( e , new [ ] { ExpressionType . Parameter } ) ;
1382
+ }
1383
+
1384
+ /// <summary>
1385
+ /// Determines whether the expression is the parameter or convert.
1386
+ /// </summary>
1387
+ /// <param name="e">The specified expression.</param>
1388
+ /// <returns>Returns true if the specified expression is parameter or convert;
1389
+ /// otherwise, false.</returns>
1390
+ protected virtual bool IsParameterOrConvertAccess ( Expression e )
1391
+ {
1392
+ return CheckExpressionForTypes ( e , new [ ] { ExpressionType . Parameter , ExpressionType . Convert } ) ;
1393
+ }
1394
+
1395
+ protected bool CheckExpressionForTypes ( Expression e , ExpressionType [ ] types )
1396
+ {
1397
+ while ( e != null )
1398
+ {
1399
+ if ( types . Contains ( e . NodeType ) )
1400
+ {
1401
+ var isSubExprAccess = e is UnaryExpression &&
1402
+ ( ( UnaryExpression ) e ) . Operand is IndexExpression ;
1403
+
1404
+ if ( ! isSubExprAccess )
1405
+ return true ;
1406
+ }
1407
+
1408
+ if ( e is BinaryExpression )
1409
+ {
1410
+ if ( CheckExpressionForTypes ( ( ( BinaryExpression ) e ) . Left , types ) )
1411
+ return true ;
1412
+
1413
+ if ( CheckExpressionForTypes ( ( ( BinaryExpression ) e ) . Right , types ) )
1414
+ return true ;
1415
+ }
1416
+
1417
+ if ( e is MethodCallExpression )
1418
+ {
1419
+ for ( int i = 0 ; i < ( ( MethodCallExpression ) e ) . Arguments . Count ; i ++ )
1420
+ {
1421
+ if ( CheckExpressionForTypes ( ( ( MethodCallExpression ) e ) . Arguments [ 0 ] , types ) )
1422
+ return true ;
1423
+ }
1424
+ }
1425
+
1426
+ if ( e is UnaryExpression )
1427
+ {
1428
+ if ( CheckExpressionForTypes ( ( ( UnaryExpression ) e ) . Operand , types ) )
1429
+ return true ;
1430
+ }
1431
+
1432
+ e = e is MemberExpression ? ( ( MemberExpression ) e ) . Expression : null ;
1433
+ }
1434
+
1435
+ return false ;
1436
+ }
1437
+
1358
1438
private static void Swap ( ref object left , ref object right )
1359
1439
{
1360
1440
var temp = right ;
@@ -1403,19 +1483,14 @@ protected virtual object VisitMemberAccess(MemberExpression m)
1403
1483
throw new ArgumentException ( string . Format ( "Expression '{0}' accesses unsupported property '{1}' of Nullable<T>" , m , m . Member ) ) ;
1404
1484
}
1405
1485
1406
- if ( m . Expression . NodeType == ExpressionType . Parameter || m . Expression . NodeType == ExpressionType . Convert )
1407
- {
1408
- var isSubExprAccess = m . Expression is UnaryExpression &&
1409
- ( ( UnaryExpression ) m . Expression ) . Operand is IndexExpression ;
1410
- if ( ! isSubExprAccess )
1411
- return GetMemberExpression ( m ) ;
1412
- }
1486
+ if ( IsParameterOrConvertAccess ( m ) )
1487
+ return GetMemberExpression ( m ) ;
1413
1488
}
1414
1489
1415
1490
return CachedExpressionCompiler . Evaluate ( m ) ;
1416
1491
}
1417
1492
1418
- private object GetMemberExpression ( MemberExpression m )
1493
+ protected virtual object GetMemberExpression ( MemberExpression m )
1419
1494
{
1420
1495
var propertyInfo = m . Member as PropertyInfo ;
1421
1496
@@ -1482,8 +1557,8 @@ private object SetAnonTypePropertyNamesForSelectExpression(object expr, Expressi
1482
1557
// to allow the caller to distinguish properties with the same names from different tables
1483
1558
1484
1559
var paramExpr = arg as ParameterExpression ;
1485
- var selectList = paramExpr != null && paramExpr . Name != member . Name
1486
- ? expr as SelectList
1560
+ var selectList = paramExpr != null && paramExpr . Name != member . Name
1561
+ ? expr as SelectList
1487
1562
: null ;
1488
1563
if ( selectList != null )
1489
1564
{
@@ -1567,7 +1642,13 @@ protected virtual object VisitUnary(UnaryExpression u)
1567
1642
return GetNotValue ( o ) ;
1568
1643
case ExpressionType . Convert :
1569
1644
if ( u . Method != null )
1645
+ {
1646
+ var e = u . Operand ;
1647
+ if ( IsParameterAccess ( e ) )
1648
+ return Visit ( e ) ;
1649
+
1570
1650
return CachedExpressionCompiler . Evaluate ( u ) ;
1651
+ }
1571
1652
break ;
1572
1653
}
1573
1654
return Visit ( u . Operand ) ;
@@ -1587,7 +1668,7 @@ protected virtual object VisitIndexExpression(IndexExpression e)
1587
1668
var list = oCollection as List < object > ;
1588
1669
if ( list != null )
1589
1670
return list [ index ] ;
1590
-
1671
+
1591
1672
throw new NotImplementedException ( "Unknown Expression: " + e ) ;
1592
1673
}
1593
1674
@@ -1606,12 +1687,10 @@ private bool IsColumnAccess(MethodCallExpression m)
1606
1687
{
1607
1688
if ( m . Object != null && m . Object as MethodCallExpression != null )
1608
1689
return IsColumnAccess ( m . Object as MethodCallExpression ) ;
1609
-
1690
+
1610
1691
var exp = m . Object as MemberExpression ;
1611
- return exp != null
1612
- && exp . Expression != null
1613
- && IsJoinedTable ( exp . Expression . Type )
1614
- && exp . Expression . NodeType == ExpressionType . Parameter ;
1692
+ return IsParameterAccess ( exp )
1693
+ && IsJoinedTable ( exp . Expression . Type ) ;
1615
1694
}
1616
1695
1617
1696
protected virtual object VisitMethodCall ( MethodCallExpression m )
@@ -1732,11 +1811,11 @@ protected virtual string GetQuotedColumnName(ModelDefinition tableDef, string me
1732
1811
if ( useFieldName )
1733
1812
{
1734
1813
var fd = tableDef . FieldDefinitions . FirstOrDefault ( x => x . Name == memberName ) ;
1735
- var fieldName = fd != null
1736
- ? fd . FieldName
1814
+ var fieldName = fd != null
1815
+ ? fd . FieldName
1737
1816
: memberName ;
1738
1817
1739
- return PrefixFieldWithTableName
1818
+ return PrefixFieldWithTableName
1740
1819
? DialectProvider . GetQuotedColumnName ( tableDef , fieldName )
1741
1820
: DialectProvider . GetQuotedColumnName ( fieldName ) ;
1742
1821
}
@@ -1941,7 +2020,7 @@ protected string ConvertInExpressionToSql(MethodCallExpression m, object quotedC
1941
2020
string sqlIn = CreateInParamSql ( inArgs ) ;
1942
2021
return string . Format ( "{0} {1} ({2})" , quotedColName , m . Method . Name , sqlIn ) ;
1943
2022
}
1944
-
2023
+
1945
2024
var exprArg = argValue as ISqlExpression ;
1946
2025
if ( exprArg != null )
1947
2026
{
0 commit comments