8
8
using System . Reflection ;
9
9
using System . Text ;
10
10
using System . Text . RegularExpressions ;
11
+ using System . Xml . Linq ;
11
12
12
13
namespace CSQLQueryExpress
13
14
{
@@ -710,6 +711,48 @@ private Expression VisitStringMethodCall(MethodCallExpression node)
710
711
throw new NotSupportedException ( string . Format ( "The method '{0}' is not supported." , node . Method . Name ) ) ;
711
712
}
712
713
714
+ private Expression VisitStringNegationMethodCall ( MethodCallExpression node )
715
+ {
716
+ if ( node . Method . Name == nameof ( string . StartsWith ) )
717
+ {
718
+ _queryBuilder . Append ( "(" ) ;
719
+ this . Visit ( node . Object ) ;
720
+ _queryBuilder . Append ( " NOT LIKE " ) ;
721
+ var valueExpression = ( ConstantExpression ) node . Arguments [ 0 ] ;
722
+ var parameterName = _parametersBuilder . AddParameter ( $ "{ valueExpression . Value } %") ;
723
+ _queryBuilder . Append ( parameterName ) ;
724
+ _queryBuilder . Append ( ")" ) ;
725
+
726
+ return node ;
727
+ }
728
+ else if ( node . Method . Name == nameof ( string . EndsWith ) )
729
+ {
730
+ _queryBuilder . Append ( "(" ) ;
731
+ this . Visit ( node . Object ) ;
732
+ _queryBuilder . Append ( " NOT LIKE " ) ;
733
+ var valueExpression = ( ConstantExpression ) node . Arguments [ 0 ] ;
734
+ var parameterName = _parametersBuilder . AddParameter ( $ "%{ valueExpression . Value } ") ;
735
+ _queryBuilder . Append ( parameterName ) ;
736
+ _queryBuilder . Append ( ")" ) ;
737
+
738
+ return node ;
739
+ }
740
+ else if ( node . Method . Name == nameof ( string . Contains ) )
741
+ {
742
+ _queryBuilder . Append ( "(" ) ;
743
+ this . Visit ( node . Object ) ;
744
+ _queryBuilder . Append ( " NOT LIKE " ) ;
745
+ var valueExpression = ( ConstantExpression ) node . Arguments [ 0 ] ;
746
+ var parameterName = _parametersBuilder . AddParameter ( $ "%{ valueExpression . Value } %") ;
747
+ _queryBuilder . Append ( parameterName ) ;
748
+ _queryBuilder . Append ( ")" ) ;
749
+
750
+ return node ;
751
+ }
752
+
753
+ throw new NotSupportedException ( string . Format ( "The method '{0}' is not supported." , node . Method . Name ) ) ;
754
+ }
755
+
713
756
public Expression VisitQueryPaginationMethodCall ( MethodCallExpression node )
714
757
{
715
758
if ( node . Method . Name == nameof ( SQLQueryPaginationExtensions . Offset ) )
@@ -976,6 +1019,21 @@ private Expression VisitQueryDefinitionMethodCall(MethodCallExpression node)
976
1019
977
1020
return node ;
978
1021
}
1022
+ else if ( node . Method . Name == nameof ( SQLQueryDefinitionExtensions . Precision ) )
1023
+ {
1024
+ this . Visit ( node . Arguments [ 0 ] ) ;
1025
+
1026
+ if ( node . Arguments . Count == 1 )
1027
+ {
1028
+ _queryBuilder . Append ( $ "({ ( ( ConstantExpression ) node . Arguments [ 1 ] ) . Value } )") ;
1029
+ }
1030
+ else
1031
+ {
1032
+ _queryBuilder . Append ( $ "({ ( ( ConstantExpression ) node . Arguments [ 1 ] ) . Value } , { ( ( ConstantExpression ) node . Arguments [ 2 ] ) . Value } )") ;
1033
+ }
1034
+
1035
+ return node ;
1036
+ }
979
1037
if ( node . Method . Name == nameof ( SQLQueryDefinitionExtensions . Asc ) )
980
1038
{
981
1039
Visit ( node . Arguments [ 0 ] ) ;
@@ -998,50 +1056,25 @@ private Expression VisitQueryConditionMethodCall(MethodCallExpression node)
998
1056
{
999
1057
if ( node . Method . Name == nameof ( SQLQueryConditionExtension . IsNull ) )
1000
1058
{
1001
- if ( node . Arguments . Count == 1 )
1002
- {
1003
- _queryBuilder . Append ( "(" ) ;
1004
- this . Visit ( node . Arguments [ 0 ] ) ;
1005
- _queryBuilder . Append ( " IS NULL" ) ;
1006
- _queryBuilder . Append ( ")" ) ;
1007
- }
1008
- else
1009
- {
1010
- _queryBuilder . Append ( "ISNULL(" ) ;
1011
- this . Visit ( node . Arguments [ 0 ] ) ;
1012
- _queryBuilder . Append ( ", " ) ;
1013
- this . Visit ( node . Arguments [ 1 ] ) ;
1014
- _queryBuilder . Append ( ")" ) ;
1015
- }
1059
+ TranslateIsNullCondition ( node ) ;
1016
1060
1017
1061
return node ;
1018
1062
}
1019
1063
else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . IsNotNull ) )
1020
1064
{
1021
- _queryBuilder . Append ( "(" ) ;
1022
- this . Visit ( node . Arguments [ 0 ] ) ;
1023
- _queryBuilder . Append ( " IS NOT NULL" ) ;
1024
- _queryBuilder . Append ( ")" ) ;
1065
+ TranslateIsNotNullCondition ( node ) ;
1025
1066
1026
1067
return node ;
1027
1068
}
1028
1069
else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . In ) )
1029
1070
{
1030
- _queryBuilder . Append ( "(" ) ;
1031
- this . Visit ( node . Arguments [ 0 ] ) ;
1032
- _queryBuilder . Append ( " IN (" ) ;
1033
- this . Visit ( node . Arguments [ 1 ] ) ;
1034
- _queryBuilder . Append ( "))" ) ;
1071
+ TranslateInCondition ( node ) ;
1035
1072
1036
1073
return node ;
1037
1074
}
1038
1075
else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . NotIn ) )
1039
1076
{
1040
- _queryBuilder . Append ( "(" ) ;
1041
- this . Visit ( node . Arguments [ 0 ] ) ;
1042
- _queryBuilder . Append ( " NOT IN (" ) ;
1043
- this . Visit ( node . Arguments [ 1 ] ) ;
1044
- _queryBuilder . Append ( "))" ) ;
1077
+ TranslateNotInCondition ( node ) ;
1045
1078
1046
1079
return node ;
1047
1080
}
@@ -1054,42 +1087,161 @@ private Expression VisitQueryConditionMethodCall(MethodCallExpression node)
1054
1087
}
1055
1088
else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . Exists ) )
1056
1089
{
1057
- _queryBuilder . Append ( "EXISTS " ) ;
1058
- this . Visit ( node . Arguments [ 1 ] ) ;
1090
+ TranslateExistsCondition ( node ) ;
1059
1091
1060
1092
return node ;
1061
1093
}
1062
1094
else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . NotExists ) )
1063
1095
{
1064
- _queryBuilder . Append ( "NOT EXISTS " ) ;
1065
- this . Visit ( node . Arguments [ 1 ] ) ;
1096
+ TranslateNotExistsCondition ( node ) ;
1066
1097
1067
1098
return node ;
1068
1099
}
1069
1100
else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . Between ) )
1070
1101
{
1071
- this . Visit ( node . Arguments [ 0 ] ) ;
1072
- _queryBuilder . Append ( " BETWEEN " ) ;
1073
- this . Visit ( node . Arguments [ 1 ] ) ;
1074
- _queryBuilder . Append ( " AND " ) ;
1075
- this . Visit ( node . Arguments [ 2 ] ) ;
1102
+ TranslateBetweenCondition ( node ) ;
1076
1103
1077
1104
return node ;
1078
1105
}
1079
1106
else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . NotBetween ) )
1080
1107
{
1081
- this . Visit ( node . Arguments [ 0 ] ) ;
1082
- _queryBuilder . Append ( " NOT BETWEEN " ) ;
1083
- this . Visit ( node . Arguments [ 1 ] ) ;
1084
- _queryBuilder . Append ( " AND " ) ;
1085
- this . Visit ( node . Arguments [ 2 ] ) ;
1108
+ TranslateNotBetweenCondition ( node ) ;
1086
1109
1087
1110
return node ;
1088
1111
}
1089
1112
1090
1113
throw new NotSupportedException ( string . Format ( "The method '{0}' is not supported." , node . Method . Name ) ) ;
1091
1114
}
1092
1115
1116
+ private Expression VisitQueryConditionNegationMethodCall ( MethodCallExpression node )
1117
+ {
1118
+ if ( node . Method . Name == nameof ( SQLQueryConditionExtension . IsNull ) )
1119
+ {
1120
+ TranslateIsNotNullCondition ( node ) ;
1121
+
1122
+ return node ;
1123
+ }
1124
+ else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . IsNotNull ) )
1125
+ {
1126
+ TranslateIsNullCondition ( node ) ;
1127
+
1128
+ return node ;
1129
+ }
1130
+ else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . In ) )
1131
+ {
1132
+ TranslateNotInCondition ( node ) ;
1133
+
1134
+ return node ;
1135
+ }
1136
+ else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . NotIn ) )
1137
+ {
1138
+ TranslateInCondition ( node ) ;
1139
+
1140
+ return node ;
1141
+ }
1142
+ else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . Exists ) )
1143
+ {
1144
+ TranslateNotExistsCondition ( node ) ;
1145
+
1146
+ return node ;
1147
+ }
1148
+ else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . NotExists ) )
1149
+ {
1150
+ TranslateExistsCondition ( node ) ;
1151
+
1152
+ return node ;
1153
+ }
1154
+ else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . Between ) )
1155
+ {
1156
+ TranslateNotBetweenCondition ( node ) ;
1157
+
1158
+ return node ;
1159
+ }
1160
+ else if ( node . Method . Name == nameof ( SQLQueryConditionExtension . NotBetween ) )
1161
+ {
1162
+ TranslateBetweenCondition ( node ) ;
1163
+
1164
+ return node ;
1165
+ }
1166
+
1167
+ throw new NotSupportedException ( string . Format ( "The method '{0}' is not supported." , node . Method . Name ) ) ;
1168
+ }
1169
+
1170
+ private void TranslateBetweenCondition ( MethodCallExpression methodCallExp )
1171
+ {
1172
+ this . Visit ( methodCallExp . Arguments [ 0 ] ) ;
1173
+ _queryBuilder . Append ( " BETWEEN " ) ;
1174
+ this . Visit ( methodCallExp . Arguments [ 1 ] ) ;
1175
+ _queryBuilder . Append ( " AND " ) ;
1176
+ this . Visit ( methodCallExp . Arguments [ 2 ] ) ;
1177
+ }
1178
+
1179
+ private void TranslateNotBetweenCondition ( MethodCallExpression methodCallExp )
1180
+ {
1181
+ this . Visit ( methodCallExp . Arguments [ 0 ] ) ;
1182
+ _queryBuilder . Append ( " NOT BETWEEN " ) ;
1183
+ this . Visit ( methodCallExp . Arguments [ 1 ] ) ;
1184
+ _queryBuilder . Append ( " AND " ) ;
1185
+ this . Visit ( methodCallExp . Arguments [ 2 ] ) ;
1186
+ }
1187
+
1188
+ private void TranslateExistsCondition ( MethodCallExpression methodCallExp )
1189
+ {
1190
+ _queryBuilder . Append ( "EXISTS " ) ;
1191
+ this . Visit ( methodCallExp . Arguments [ 1 ] ) ;
1192
+ }
1193
+
1194
+ private void TranslateNotExistsCondition ( MethodCallExpression methodCallExp )
1195
+ {
1196
+ _queryBuilder . Append ( "NOT EXISTS " ) ;
1197
+ this . Visit ( methodCallExp . Arguments [ 1 ] ) ;
1198
+ }
1199
+
1200
+ private void TranslateInCondition ( MethodCallExpression methodCallExp )
1201
+ {
1202
+ _queryBuilder . Append ( "(" ) ;
1203
+ this . Visit ( methodCallExp . Arguments [ 0 ] ) ;
1204
+ _queryBuilder . Append ( " IN (" ) ;
1205
+ this . Visit ( methodCallExp . Arguments [ 1 ] ) ;
1206
+ _queryBuilder . Append ( "))" ) ;
1207
+ }
1208
+
1209
+ private void TranslateNotInCondition ( MethodCallExpression methodCallExp )
1210
+ {
1211
+ _queryBuilder . Append ( "(" ) ;
1212
+ this . Visit ( methodCallExp . Arguments [ 0 ] ) ;
1213
+ _queryBuilder . Append ( " NOT IN (" ) ;
1214
+ this . Visit ( methodCallExp . Arguments [ 1 ] ) ;
1215
+ _queryBuilder . Append ( "))" ) ;
1216
+ }
1217
+
1218
+ private void TranslateIsNullCondition ( MethodCallExpression methodCallExp )
1219
+ {
1220
+ if ( methodCallExp . Arguments . Count == 1 )
1221
+ {
1222
+ _queryBuilder . Append ( "(" ) ;
1223
+ this . Visit ( methodCallExp . Arguments [ 0 ] ) ;
1224
+ _queryBuilder . Append ( " IS NULL" ) ;
1225
+ _queryBuilder . Append ( ")" ) ;
1226
+ }
1227
+ else
1228
+ {
1229
+ _queryBuilder . Append ( "ISNULL(" ) ;
1230
+ this . Visit ( methodCallExp . Arguments [ 0 ] ) ;
1231
+ _queryBuilder . Append ( ", " ) ;
1232
+ this . Visit ( methodCallExp . Arguments [ 1 ] ) ;
1233
+ _queryBuilder . Append ( ")" ) ;
1234
+ }
1235
+ }
1236
+
1237
+ private void TranslateIsNotNullCondition ( MethodCallExpression methodCallExp )
1238
+ {
1239
+ _queryBuilder . Append ( "(" ) ;
1240
+ this . Visit ( methodCallExp . Arguments [ 0 ] ) ;
1241
+ _queryBuilder . Append ( " IS NOT NULL" ) ;
1242
+ _queryBuilder . Append ( ")" ) ;
1243
+ }
1244
+
1093
1245
private Expression VisitQueryOperationMethodCall ( MethodCallExpression node )
1094
1246
{
1095
1247
if ( node . Method . Name == nameof ( SQLQueryOperationExtensions . Sum ) )
@@ -1627,6 +1779,21 @@ protected override Expression VisitUnary(UnaryExpression node)
1627
1779
1628
1780
return node ;
1629
1781
}
1782
+ else if ( _fragmentType == SQLQueryFragmentType . Where &&
1783
+ node . NodeType == ExpressionType . Not &&
1784
+ node . Operand . NodeType == ExpressionType . Call )
1785
+ {
1786
+ var methodCallExp = ( MethodCallExpression ) node . Operand ;
1787
+ var declaringType = methodCallExp . Method . DeclaringType ;
1788
+ if ( declaringType == typeof ( SQLQueryConditionExtension ) )
1789
+ {
1790
+ return VisitQueryConditionNegationMethodCall ( methodCallExp ) ;
1791
+ }
1792
+ else if ( declaringType == typeof ( string ) )
1793
+ {
1794
+ return VisitStringNegationMethodCall ( methodCallExp ) ;
1795
+ }
1796
+ }
1630
1797
1631
1798
return base . VisitUnary ( node ) ;
1632
1799
}
0 commit comments