Skip to content

Commit a47b8c0

Browse files
committed
- 优化 IIF 表达式解析;
1 parent a7b40e9 commit a47b8c0

File tree

2 files changed

+261
-1
lines changed

2 files changed

+261
-1
lines changed
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Data.Common;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using Microsoft.Data.SqlClient;
8+
using Xunit;
9+
10+
namespace FreeSql.Tests.Internal
11+
{
12+
13+
public class CommonExpressionTest
14+
{
15+
[Fact]
16+
public void IIFTest01()
17+
{
18+
var fsql = g.sqlite;
19+
var sql = "";
20+
var sb = new StringBuilder();
21+
22+
sql = fsql.Select<IIFTest01Model>().Where(a => a.Bool == true).ToSql();
23+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
24+
FROM ""IIFTest01Model"" a
25+
WHERE (a.""Bool"" = 1)", sql);
26+
sql = fsql.Select<IIFTest01Model>().Where(a => a.Bool != true).ToSql();
27+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
28+
FROM ""IIFTest01Model"" a
29+
WHERE (a.""Bool"" <> 1)", sql);
30+
sql = fsql.Select<IIFTest01Model>().Where(a => a.Bool == false).ToSql();
31+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
32+
FROM ""IIFTest01Model"" a
33+
WHERE (a.""Bool"" = 0)", sql);
34+
sql = fsql.Select<IIFTest01Model>().Where(a => !a.Bool).ToSql();
35+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
36+
FROM ""IIFTest01Model"" a
37+
WHERE (a.""Bool"" = 0)", sql);
38+
sql = fsql.Select<IIFTest01Model>().Where(a => a.Bool).ToSql();
39+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
40+
FROM ""IIFTest01Model"" a
41+
WHERE (a.""Bool"" = 1)", sql);
42+
sql = fsql.Select<IIFTest01Model>().WhereCascade(a => a.Bool).Limit(10).ToSql();
43+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
44+
FROM ""IIFTest01Model"" a
45+
WHERE (a.""Bool"" = 1)
46+
limit 0,10", sql);
47+
48+
sql = fsql.Select<IIFTest01Model>().Where(a => a.BoolNullable == true).ToSql();
49+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
50+
FROM ""IIFTest01Model"" a
51+
WHERE (a.""BoolNullable"" = 1)", sql);
52+
sql = fsql.Select<IIFTest01Model>().Where(a => a.BoolNullable != true).ToSql();
53+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
54+
FROM ""IIFTest01Model"" a
55+
WHERE (a.""BoolNullable"" <> 1)", sql);
56+
sql = fsql.Select<IIFTest01Model>().Where(a => a.BoolNullable == false).ToSql();
57+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
58+
FROM ""IIFTest01Model"" a
59+
WHERE (a.""BoolNullable"" = 0)", sql);
60+
sql = fsql.Select<IIFTest01Model>().Where(a => !a.BoolNullable.Value).ToSql();
61+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
62+
FROM ""IIFTest01Model"" a
63+
WHERE (a.""BoolNullable"" = 0)", sql);
64+
sql = fsql.Select<IIFTest01Model>().Where(a => a.BoolNullable.Value).ToSql();
65+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
66+
FROM ""IIFTest01Model"" a
67+
WHERE (a.""BoolNullable"" = 1)", sql);
68+
69+
sql = fsql.Select<IIFTest01Model>().Where(a => a.Bool == true && a.Id > 0).ToSql();
70+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
71+
FROM ""IIFTest01Model"" a
72+
WHERE (a.""Bool"" = 1 AND a.""Id"" > 0)", sql);
73+
sql = fsql.Select<IIFTest01Model>().Where(a => a.Bool != true && a.Id > 0).ToSql();
74+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
75+
FROM ""IIFTest01Model"" a
76+
WHERE (a.""Bool"" <> 1 AND a.""Id"" > 0)", sql);
77+
sql = fsql.Select<IIFTest01Model>().Where(a => a.Bool == false && a.Id > 0).ToSql();
78+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
79+
FROM ""IIFTest01Model"" a
80+
WHERE (a.""Bool"" = 0 AND a.""Id"" > 0)", sql);
81+
sql = fsql.Select<IIFTest01Model>().Where(a => !a.Bool && a.Id > 0).ToSql();
82+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
83+
FROM ""IIFTest01Model"" a
84+
WHERE (a.""Bool"" = 0 AND a.""Id"" > 0)", sql);
85+
sql = fsql.Select<IIFTest01Model>().Where(a => a.Bool && a.Id > 0).ToSql();
86+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
87+
FROM ""IIFTest01Model"" a
88+
WHERE (a.""Bool"" = 1 AND a.""Id"" > 0)", sql);
89+
90+
sql = fsql.Select<IIFTest01Model>().Where(a => a.BoolNullable == true && a.Id > 0).ToSql();
91+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
92+
FROM ""IIFTest01Model"" a
93+
WHERE (a.""BoolNullable"" = 1 AND a.""Id"" > 0)", sql);
94+
sql = fsql.Select<IIFTest01Model>().Where(a => a.BoolNullable != true && a.Id > 0).ToSql();
95+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
96+
FROM ""IIFTest01Model"" a
97+
WHERE (a.""BoolNullable"" <> 1 AND a.""Id"" > 0)", sql);
98+
sql = fsql.Select<IIFTest01Model>().Where(a => a.BoolNullable == false && a.Id > 0).ToSql();
99+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
100+
FROM ""IIFTest01Model"" a
101+
WHERE (a.""BoolNullable"" = 0 AND a.""Id"" > 0)", sql);
102+
sql = fsql.Select<IIFTest01Model>().Where(a => !a.BoolNullable.Value && a.Id > 0).ToSql();
103+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
104+
FROM ""IIFTest01Model"" a
105+
WHERE (a.""BoolNullable"" = 0 AND a.""Id"" > 0)", sql);
106+
sql = fsql.Select<IIFTest01Model>().Where(a => a.BoolNullable.Value && a.Id > 0).ToSql();
107+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
108+
FROM ""IIFTest01Model"" a
109+
WHERE (a.""BoolNullable"" = 1 AND a.""Id"" > 0)", sql);
110+
111+
sql = fsql.Select<IIFTest01Model>().Where(a => a.Bool == true && a.Id > 0 && a.Bool == true).ToSql();
112+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
113+
FROM ""IIFTest01Model"" a
114+
WHERE (a.""Bool"" = 1 AND a.""Id"" > 0 AND a.""Bool"" = 1)", sql);
115+
sql = fsql.Select<IIFTest01Model>().Where(a => a.Bool != true && a.Id > 0 && a.Bool != true).ToSql();
116+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
117+
FROM ""IIFTest01Model"" a
118+
WHERE (a.""Bool"" <> 1 AND a.""Id"" > 0 AND a.""Bool"" <> 1)", sql);
119+
sql = fsql.Select<IIFTest01Model>().Where(a => a.Bool == false && a.Id > 0 && a.Bool == false).ToSql();
120+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
121+
FROM ""IIFTest01Model"" a
122+
WHERE (a.""Bool"" = 0 AND a.""Id"" > 0 AND a.""Bool"" = 0)", sql);
123+
sql = fsql.Select<IIFTest01Model>().Where(a => !a.Bool && a.Id > 0 && !a.Bool).ToSql();
124+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
125+
FROM ""IIFTest01Model"" a
126+
WHERE (a.""Bool"" = 0 AND a.""Id"" > 0 AND a.""Bool"" = 0)", sql);
127+
sql = fsql.Select<IIFTest01Model>().Where(a => a.Bool && a.Id > 0 && a.Bool).ToSql();
128+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
129+
FROM ""IIFTest01Model"" a
130+
WHERE (a.""Bool"" = 1 AND a.""Id"" > 0 AND a.""Bool"" = 1)", sql);
131+
132+
sql = fsql.Select<IIFTest01Model>().Where(a => a.BoolNullable == true && a.Id > 0 && a.BoolNullable == true).ToSql();
133+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
134+
FROM ""IIFTest01Model"" a
135+
WHERE (a.""BoolNullable"" = 1 AND a.""Id"" > 0 AND a.""BoolNullable"" = 1)", sql);
136+
sql = fsql.Select<IIFTest01Model>().Where(a => a.BoolNullable != true && a.Id > 0 && a.BoolNullable != true).ToSql();
137+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
138+
FROM ""IIFTest01Model"" a
139+
WHERE (a.""BoolNullable"" <> 1 AND a.""Id"" > 0 AND a.""BoolNullable"" <> 1)", sql);
140+
sql = fsql.Select<IIFTest01Model>().Where(a => a.BoolNullable == false && a.Id > 0 && a.BoolNullable == false).ToSql();
141+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
142+
FROM ""IIFTest01Model"" a
143+
WHERE (a.""BoolNullable"" = 0 AND a.""Id"" > 0 AND a.""BoolNullable"" = 0)", sql);
144+
sql = fsql.Select<IIFTest01Model>().Where(a => !a.BoolNullable.Value && a.Id > 0 && !a.BoolNullable.Value).ToSql();
145+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
146+
FROM ""IIFTest01Model"" a
147+
WHERE (a.""BoolNullable"" = 0 AND a.""Id"" > 0 AND a.""BoolNullable"" = 0)", sql);
148+
sql = fsql.Select<IIFTest01Model>().Where(a => a.BoolNullable.Value && a.Id > 0 && a.BoolNullable.Value).ToSql();
149+
Assert.Equal(@"SELECT a.""Id"", a.""Bool"", a.""BoolNullable""
150+
FROM ""IIFTest01Model"" a
151+
WHERE (a.""BoolNullable"" = 1 AND a.""Id"" > 0 AND a.""BoolNullable"" = 1)", sql);
152+
153+
// IIF
154+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.Bool == true ? 10 : 11);
155+
Assert.Equal(@"SELECT (case when a.""Bool"" = 1 then 10 else 11 end) as1
156+
FROM ""IIFTest01Model"" a", sql);
157+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.Bool != true ? 10 : 11);
158+
Assert.Equal(@"SELECT (case when a.""Bool"" <> 1 then 10 else 11 end) as1
159+
FROM ""IIFTest01Model"" a", sql);
160+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.Bool == false ? 10 : 11);
161+
Assert.Equal(@"SELECT (case when a.""Bool"" = 0 then 10 else 11 end) as1
162+
FROM ""IIFTest01Model"" a", sql);
163+
sql = fsql.Select<IIFTest01Model>().ToSql(a => !a.Bool ? 10 : 11);
164+
Assert.Equal(@"SELECT (case when a.""Bool"" = 0 then 10 else 11 end) as1
165+
FROM ""IIFTest01Model"" a", sql);
166+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.Bool ? 10 : 11);
167+
Assert.Equal(@"SELECT (case when a.""Bool"" = 1 then 10 else 11 end) as1
168+
FROM ""IIFTest01Model"" a", sql);
169+
170+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable == true ? 10 : 11);
171+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" = 1 then 10 else 11 end) as1
172+
FROM ""IIFTest01Model"" a", sql);
173+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable != true ? 10 : 11);
174+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" <> 1 then 10 else 11 end) as1
175+
FROM ""IIFTest01Model"" a", sql);
176+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable == false ? 10 : 11);
177+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" = 0 then 10 else 11 end) as1
178+
FROM ""IIFTest01Model"" a", sql);
179+
sql = fsql.Select<IIFTest01Model>().ToSql(a => !a.BoolNullable.Value ? 10 : 11);
180+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" = 0 then 10 else 11 end) as1
181+
FROM ""IIFTest01Model"" a", sql);
182+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable.Value ? 10 : 11);
183+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" = 1 then 10 else 11 end) as1
184+
FROM ""IIFTest01Model"" a", sql);
185+
186+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.Bool == true && a.Id > 0 ? 10 : 11);
187+
Assert.Equal(@"SELECT (case when a.""Bool"" = 1 AND a.""Id"" > 0 then 10 else 11 end) as1
188+
FROM ""IIFTest01Model"" a", sql);
189+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.Bool != true && a.Id > 0 ? 10 : 11);
190+
Assert.Equal(@"SELECT (case when a.""Bool"" <> 1 AND a.""Id"" > 0 then 10 else 11 end) as1
191+
FROM ""IIFTest01Model"" a", sql);
192+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.Bool == false && a.Id > 0 ? 10 : 11);
193+
Assert.Equal(@"SELECT (case when a.""Bool"" = 0 AND a.""Id"" > 0 then 10 else 11 end) as1
194+
FROM ""IIFTest01Model"" a", sql);
195+
sql = fsql.Select<IIFTest01Model>().ToSql(a => !a.Bool && a.Id > 0 ? 10 : 11);
196+
Assert.Equal(@"SELECT (case when a.""Bool"" = 0 AND a.""Id"" > 0 then 10 else 11 end) as1
197+
FROM ""IIFTest01Model"" a", sql);
198+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.Bool && a.Id > 0 ? 10 : 11);
199+
Assert.Equal(@"SELECT (case when a.""Bool"" = 1 AND a.""Id"" > 0 then 10 else 11 end) as1
200+
FROM ""IIFTest01Model"" a", sql);
201+
202+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable == true && a.Id > 0 ? 10 : 11);
203+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" = 1 AND a.""Id"" > 0 then 10 else 11 end) as1
204+
FROM ""IIFTest01Model"" a", sql);
205+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable != true && a.Id > 0 ? 10 : 11);
206+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" <> 1 AND a.""Id"" > 0 then 10 else 11 end) as1
207+
FROM ""IIFTest01Model"" a", sql);
208+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable == false && a.Id > 0 ? 10 : 11);
209+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" = 0 AND a.""Id"" > 0 then 10 else 11 end) as1
210+
FROM ""IIFTest01Model"" a", sql);
211+
sql = fsql.Select<IIFTest01Model>().ToSql(a => !a.BoolNullable.Value && a.Id > 0 ? 10 : 11);
212+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" = 0 AND a.""Id"" > 0 then 10 else 11 end) as1
213+
FROM ""IIFTest01Model"" a", sql);
214+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable.Value && a.Id > 0 ? 10 : 11);
215+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" = 1 AND a.""Id"" > 0 then 10 else 11 end) as1
216+
FROM ""IIFTest01Model"" a", sql);
217+
218+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.Bool == true && a.Id > 0 && a.Bool == true ? 10 : 11);
219+
Assert.Equal(@"SELECT (case when a.""Bool"" = 1 AND a.""Id"" > 0 AND a.""Bool"" = 1 then 10 else 11 end) as1
220+
FROM ""IIFTest01Model"" a", sql);
221+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.Bool != true && a.Id > 0 && a.Bool != true ? 10 : 11);
222+
Assert.Equal(@"SELECT (case when a.""Bool"" <> 1 AND a.""Id"" > 0 AND a.""Bool"" <> 1 then 10 else 11 end) as1
223+
FROM ""IIFTest01Model"" a", sql);
224+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.Bool == false && a.Id > 0 && a.Bool == false ? 10 : 11);
225+
Assert.Equal(@"SELECT (case when a.""Bool"" = 0 AND a.""Id"" > 0 AND a.""Bool"" = 0 then 10 else 11 end) as1
226+
FROM ""IIFTest01Model"" a", sql);
227+
sql = fsql.Select<IIFTest01Model>().ToSql(a => !a.Bool && a.Id > 0 && !a.Bool ? 10 : 11);
228+
Assert.Equal(@"SELECT (case when a.""Bool"" = 0 AND a.""Id"" > 0 AND a.""Bool"" = 0 then 10 else 11 end) as1
229+
FROM ""IIFTest01Model"" a", sql);
230+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.Bool && a.Id > 0 && a.Bool ? 10 : 11);
231+
Assert.Equal(@"SELECT (case when a.""Bool"" = 1 AND a.""Id"" > 0 AND a.""Bool"" = 1 then 10 else 11 end) as1
232+
FROM ""IIFTest01Model"" a", sql);
233+
234+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable == true && a.Id > 0 && a.BoolNullable == true ? 10 : 11);
235+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" = 1 AND a.""Id"" > 0 AND a.""BoolNullable"" = 1 then 10 else 11 end) as1
236+
FROM ""IIFTest01Model"" a", sql);
237+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable != true && a.Id > 0 && a.BoolNullable != true ? 10 : 11);
238+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" <> 1 AND a.""Id"" > 0 AND a.""BoolNullable"" <> 1 then 10 else 11 end) as1
239+
FROM ""IIFTest01Model"" a", sql);
240+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable == false && a.Id > 0 && a.BoolNullable == false ? 10 : 11);
241+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" = 0 AND a.""Id"" > 0 AND a.""BoolNullable"" = 0 then 10 else 11 end) as1
242+
FROM ""IIFTest01Model"" a", sql);
243+
sql = fsql.Select<IIFTest01Model>().ToSql(a => !a.BoolNullable.Value && a.Id > 0 && !a.BoolNullable.Value ? 10 : 11);
244+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" = 0 AND a.""Id"" > 0 AND a.""BoolNullable"" = 0 then 10 else 11 end) as1
245+
FROM ""IIFTest01Model"" a", sql);
246+
sql = fsql.Select<IIFTest01Model>().ToSql(a => a.BoolNullable.Value && a.Id > 0 && a.BoolNullable.Value ? 10 : 11);
247+
Assert.Equal(@"SELECT (case when a.""BoolNullable"" = 1 AND a.""Id"" > 0 AND a.""BoolNullable"" = 1 then 10 else 11 end) as1
248+
FROM ""IIFTest01Model"" a", sql);
249+
}
250+
251+
class IIFTest01Model
252+
{
253+
public int Id { get; set; }
254+
public bool Bool { get; set; }
255+
public bool? BoolNullable { get; set; }
256+
}
257+
}
258+
}

FreeSql/Internal/CommonExpression.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,9 @@ public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc)
759759
var conditionalTestOldMapType = tsc.SetMapTypeReturnOld(null);
760760
if (condExp.Test.IsParameter())
761761
{
762-
var conditionalTestSql = ExpressionLambdaToSql(condExp.Test, tsc);
762+
var condExp2 = condExp.Test;
763+
if (condExp2.NodeType == ExpressionType.MemberAccess) condExp2 = Expression.Equal(condExp2, Expression.Constant(true));
764+
var conditionalTestSql = ExpressionLambdaToSql(condExp2, tsc);
763765
tsc.SetMapTypeReturnOld(conditionalTestOldMapType);
764766
var conditionalSql = _common.IIF(conditionalTestSql, ExpressionLambdaToSql(condExp.IfTrue, tsc), ExpressionLambdaToSql(condExp.IfFalse, tsc));
765767
tsc.SetMapTypeReturnOld(null);

0 commit comments

Comments
 (0)