1
+ using System . Data ;
2
+ using System . Linq ;
3
+ using NUnit . Framework ;
4
+ using ServiceStack . OrmLite . Tests . UseCase ;
5
+ using ServiceStack . Text ;
6
+
7
+ namespace ServiceStack . OrmLite . Tests
8
+ {
9
+ public class LoadReferencesJoinTests
10
+ : OrmLiteTestBase
11
+ {
12
+ private IDbConnection db ;
13
+
14
+ [ TestFixtureSetUp ]
15
+ public new void TestFixtureSetUp ( )
16
+ {
17
+ db = base . OpenDbConnection ( ) ;
18
+ CustomerOrdersUseCase . DropTables ( db ) ; //Has conflicting 'Order' table
19
+
20
+ db . DropAndCreateTable < Order > ( ) ;
21
+ db . DropAndCreateTable < Customer > ( ) ;
22
+ db . DropAndCreateTable < CustomerAddress > ( ) ;
23
+ db . DropAndCreateTable < Country > ( ) ;
24
+ }
25
+
26
+ [ SetUp ]
27
+ public void SetUp ( )
28
+ {
29
+ db . DeleteAll < Order > ( ) ;
30
+ db . DeleteAll < CustomerAddress > ( ) ;
31
+ db . DeleteAll < Customer > ( ) ;
32
+ db . DeleteAll < Country > ( ) ;
33
+ }
34
+
35
+ [ TestFixtureTearDown ]
36
+ public void TestFixtureTearDown ( )
37
+ {
38
+ db . Dispose ( ) ;
39
+ }
40
+
41
+ private Customer AddCustomerWithOrders ( )
42
+ {
43
+ var customer = new Customer
44
+ {
45
+ Name = "Customer 1" ,
46
+ PrimaryAddress = new CustomerAddress
47
+ {
48
+ AddressLine1 = "1 Humpty Street" ,
49
+ City = "Humpty Doo" ,
50
+ State = "Northern Territory" ,
51
+ Country = "Australia"
52
+ } ,
53
+ Orders = new [ ]
54
+ {
55
+ new Order { LineItem = "Line 1" , Qty = 1 , Cost = 1.99m } ,
56
+ new Order { LineItem = "Line 2" , Qty = 2 , Cost = 2.99m } ,
57
+ } . ToList ( ) ,
58
+ } ;
59
+
60
+ db . Save ( customer , references : true ) ;
61
+
62
+ return customer ;
63
+ }
64
+
65
+ public class CustomerJoin
66
+ {
67
+ public int Id { get ; set ; }
68
+ public string Name { get ; set ; }
69
+ public string AddressLine1 { get ; set ; }
70
+ public string City { get ; set ; }
71
+ public string LineItem { get ; set ; }
72
+ public decimal Cost { get ; set ; }
73
+ public string CountryCode { get ; set ; }
74
+ }
75
+
76
+ [ Test ]
77
+ public void Can_do_multiple_joins_with_SqlExpression ( )
78
+ {
79
+ AddCustomerWithOrders ( ) ;
80
+
81
+ var results = db . Select < CustomerJoin , Customer > ( q => q
82
+ . Join < Customer , CustomerAddress > ( )
83
+ . Join < Customer , Order > ( ) ) ;
84
+
85
+ var costs = results . ConvertAll ( x => x . Cost ) ;
86
+ Assert . That ( costs , Is . EquivalentTo ( new [ ] { 1.99m , 2.99m } ) ) ;
87
+
88
+ var expr = db . From < Customer > ( )
89
+ . Join < Customer , CustomerAddress > ( )
90
+ . Join < Customer , Order > ( ) ;
91
+
92
+ results = db . Select < CustomerJoin > ( expr ) ;
93
+
94
+ costs = results . ConvertAll ( x => x . Cost ) ;
95
+ Assert . That ( costs , Is . EquivalentTo ( new [ ] { 1.99m , 2.99m } ) ) ;
96
+ }
97
+
98
+ [ Test ]
99
+ public void Can_do_joins_with_wheres_using_SqlExpression ( )
100
+ {
101
+ AddCustomerWithOrders ( ) ;
102
+
103
+ var results = db . Select < CustomerJoin , Customer > ( q => q
104
+ . Join < Customer , CustomerAddress > ( )
105
+ . Join < Customer , Order > ( ( c , o ) => c . Id == o . CustomerId && o . Cost < 2 ) ) ;
106
+
107
+ var costs = results . ConvertAll ( x => x . Cost ) ;
108
+ Assert . That ( costs , Is . EquivalentTo ( new [ ] { 1.99m } ) ) ;
109
+
110
+ var orders = db . Select < Order > ( q => q
111
+ . Join < Order , Customer > ( )
112
+ . Join < Customer , CustomerAddress > ( )
113
+ . Where ( o => o . Cost < 2 )
114
+ . And < Customer > ( c => c . Name == "Customer 1" ) ) ;
115
+
116
+ costs = orders . ConvertAll ( x => x . Cost ) ;
117
+ Assert . That ( costs , Is . EquivalentTo ( new [ ] { 1.99m } ) ) ;
118
+
119
+ results = db . Select < CustomerJoin , Customer > ( q => q
120
+ . Join < Customer , CustomerAddress > ( )
121
+ . Join < Customer , Order > ( )
122
+ . Where < Order > ( o => o . Cost < 2 ) ) ;
123
+
124
+ costs = results . ConvertAll ( x => x . Cost ) ;
125
+ Assert . That ( costs , Is . EquivalentTo ( new [ ] { 1.99m } ) ) ;
126
+
127
+ results = db . Select < CustomerJoin , Customer > ( q => q
128
+ . Join < Customer , CustomerAddress > ( )
129
+ . Join < Customer , Order > ( )
130
+ . Where < Order > ( o => o . Cost < 2 || o . LineItem == "Line 2" ) ) ;
131
+
132
+ costs = results . ConvertAll ( x => x . Cost ) ;
133
+ Assert . That ( costs , Is . EquivalentTo ( new [ ] { 1.99m , 2.99m } ) ) ;
134
+
135
+ var expr = db . From < Customer > ( )
136
+ . Join < Customer , CustomerAddress > ( )
137
+ . Join < Customer , Order > ( )
138
+ . Where < Order > ( o => o . Cost < 2 || o . LineItem == "Line 2" ) ;
139
+ results = db . Select < CustomerJoin > ( expr ) ;
140
+
141
+ costs = results . ConvertAll ( x => x . Cost ) ;
142
+ Assert . That ( costs , Is . EquivalentTo ( new [ ] { 1.99m , 2.99m } ) ) ;
143
+ }
144
+
145
+ [ Test ]
146
+ public void Can_do_joins_with_complex_wheres_using_SqlExpression ( )
147
+ {
148
+ var customer1 = new Customer
149
+ {
150
+ Name = "Customer 1" ,
151
+ PrimaryAddress = new CustomerAddress
152
+ {
153
+ AddressLine1 = "1 Humpty Street" ,
154
+ City = "Humpty Doo" ,
155
+ State = "Northern Territory" ,
156
+ Country = "Australia"
157
+ } ,
158
+ Orders = new [ ]
159
+ {
160
+ new Order { LineItem = "Line 1" , Qty = 1 , Cost = 1.99m } ,
161
+ new Order { LineItem = "Line 1" , Qty = 2 , Cost = 3.98m } ,
162
+ new Order { LineItem = "Line 2" , Qty = 1 , Cost = 1.49m } ,
163
+ new Order { LineItem = "Line 2" , Qty = 2 , Cost = 2.98m } ,
164
+ new Order { LineItem = "Australia Flag" , Qty = 1 , Cost = 9.99m } ,
165
+ } . ToList ( ) ,
166
+ } ;
167
+
168
+ db . Save ( customer1 , references : true ) ;
169
+
170
+ var customer2 = new Customer
171
+ {
172
+ Name = "Customer 2" ,
173
+ PrimaryAddress = new CustomerAddress
174
+ {
175
+ AddressLine1 = "2 Prospect Park" ,
176
+ City = "Brooklyn" ,
177
+ State = "New York" ,
178
+ Country = "USA"
179
+ } ,
180
+ Orders = new [ ]
181
+ {
182
+ new Order { LineItem = "USA" , Qty = 1 , Cost = 20m } ,
183
+ } . ToList ( ) ,
184
+ } ;
185
+
186
+ db . Save ( customer2 , references : true ) ;
187
+
188
+ db . Insert (
189
+ new Country { CountryName = "Australia" , CountryCode = "AU" } ,
190
+ new Country { CountryName = "USA" , CountryCode = "US" } ) ;
191
+
192
+ var results = db . Select < CustomerJoin , Customer > ( q => q
193
+ . Join < Customer , CustomerAddress > ( )
194
+ . Join < Customer , Order > ( )
195
+ . Where ( c => c . Name == "Customer 1" )
196
+ . And < Order > ( o => o . Cost < 2 )
197
+ . Or < Order > ( o => o . LineItem == "Australia Flag" ) ) ;
198
+
199
+ var costs = results . ConvertAll ( x => x . Cost ) ;
200
+ Assert . That ( costs , Is . EquivalentTo ( new [ ] { 1.99m , 1.49m , 9.99m } ) ) ;
201
+
202
+ results = db . Select < CustomerJoin , Customer > ( q => q
203
+ . Join < Customer , CustomerAddress > ( )
204
+ . Join < Customer , Order > ( )
205
+ . Where ( c => c . Name == "Customer 2" )
206
+ . And < CustomerAddress , Order > ( ( a , o ) => a . Country == o . LineItem ) ) ;
207
+
208
+ costs = results . ConvertAll ( x => x . Cost ) ;
209
+ Assert . That ( costs , Is . EquivalentTo ( new [ ] { 20m } ) ) ;
210
+
211
+ var countryResults = db . Select < CustomerJoin > ( db . From < Customer > ( )
212
+ . Join < Order > ( ( c , o ) => c . Id == o . CustomerId ) //explicit join condition
213
+ . Join < CustomerAddress > ( ) //implicit join with Customer
214
+ . Join < CustomerAddress , Country > ( ( ca , c ) => ca . Country == c . CountryName )
215
+ . Where ( c => c . Name == "Customer 2" ) //implicit condition with Customer
216
+ . And < CustomerAddress , Order > ( ( a , o ) => a . Country == o . LineItem ) ) ;
217
+
218
+ db . GetLastSql ( ) . Print ( ) ;
219
+
220
+ costs = countryResults . ConvertAll ( x => x . Cost ) ;
221
+ Assert . That ( costs , Is . EquivalentTo ( new [ ] { 20m } ) ) ;
222
+ Assert . That ( countryResults . ConvertAll ( x => x . CountryCode ) , Is . EquivalentTo ( new [ ] { "US" } ) ) ;
223
+ }
224
+
225
+ [ Test ]
226
+ public void Can_do_LeftJoins_using_SqlExpression ( )
227
+ {
228
+ var customers = new [ ]
229
+ {
230
+ new Customer
231
+ {
232
+ Name = "Customer 1" ,
233
+ PrimaryAddress = new CustomerAddress
234
+ {
235
+ AddressLine1 = "1 Humpty Street" ,
236
+ City = "Humpty Doo" ,
237
+ State = "Northern Territory" ,
238
+ Country = "Australia"
239
+ } ,
240
+ } ,
241
+ new Customer
242
+ {
243
+ Name = "Customer 2" ,
244
+ PrimaryAddress = new CustomerAddress
245
+ {
246
+ AddressLine1 = "2 Humpty Street" ,
247
+ City = "Humpty Doo" ,
248
+ State = "Northern Territory" ,
249
+ Country = "USA"
250
+ } ,
251
+ } ,
252
+ new Customer
253
+ {
254
+ Name = "Customer 3" ,
255
+ PrimaryAddress = new CustomerAddress
256
+ {
257
+ AddressLine1 = "3 Humpty Street" ,
258
+ City = "Humpty Doo" ,
259
+ State = "Northern Territory" ,
260
+ Country = "Canada"
261
+ } ,
262
+ } ,
263
+ } ;
264
+
265
+ customers . Each ( c =>
266
+ db . Save ( c , references : true ) ) ;
267
+
268
+ db . Insert (
269
+ new Country { CountryName = "Australia" , CountryCode = "AU" } ,
270
+ new Country { CountryName = "USA" , CountryCode = "US" } ,
271
+ new Country { CountryName = "Italy" , CountryCode = "IT" } ,
272
+ new Country { CountryName = "Spain" , CountryCode = "ED" } ) ;
273
+
274
+ //Normal Join
275
+ var dbCustomers = db . Select < Customer > ( q => q
276
+ . Join < CustomerAddress > ( )
277
+ . Join < CustomerAddress , Country > ( ( ca , c ) => ca . Country == c . CountryName ) ) ;
278
+
279
+ Assert . That ( dbCustomers . Count , Is . EqualTo ( 2 ) ) ;
280
+
281
+ //Left Join
282
+ dbCustomers = db . Select < Customer > ( q => q
283
+ . Join < CustomerAddress > ( )
284
+ . LeftJoin < CustomerAddress , Country > ( ( ca , c ) => ca . Country == c . CountryName ) ) ;
285
+
286
+ Assert . That ( dbCustomers . Count , Is . EqualTo ( 3 ) ) ;
287
+
288
+ //Warning: Right and Full Joins are not implemented by Sqlite3. Avoid if possible.
289
+ var dbCountries = db . Select < Country > ( q => q
290
+ . LeftJoin < CustomerAddress > ( ( c , ca ) => ca . Country == c . CountryName )
291
+ . LeftJoin < CustomerAddress , Customer > ( ) ) ;
292
+
293
+ Assert . That ( dbCountries . Count , Is . EqualTo ( 4 ) ) ;
294
+
295
+ var dbAddresses = db . Select < CustomerAddress > ( q => q
296
+ . LeftJoin < Country > ( ( ca , c ) => ca . Country == c . CountryName )
297
+ . LeftJoin < CustomerAddress , Customer > ( ) ) ;
298
+
299
+ Assert . That ( dbAddresses . Count , Is . EqualTo ( 3 ) ) ;
300
+ }
301
+
302
+ }
303
+ }
0 commit comments