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