3
3
using System . Data ;
4
4
using System . Linq ;
5
5
using NUnit . Framework ;
6
+ using ServiceStack . DataAnnotations ;
6
7
7
8
namespace ServiceStack . OrmLite . Tests
8
9
{
@@ -17,10 +18,23 @@ public void Setup()
17
18
using ( var db = OpenDbConnection ( ) )
18
19
{
19
20
db . DropAndCreateTable < TestType > ( ) ;
20
- db . Insert ( new TestType { Id = 1 , BoolCol = true , DateCol = new DateTime ( 2012 , 1 , 1 ) , TextCol = "asdf" , EnumCol = TestEnum . Val0 , NullableIntCol = 10 } ) ;
21
- db . Insert ( new TestType { Id = 2 , BoolCol = true , DateCol = new DateTime ( 2012 , 2 , 1 ) , TextCol = "asdf123" , EnumCol = TestEnum . Val1 , NullableIntCol = null } ) ;
22
- db . Insert ( new TestType { Id = 3 , BoolCol = false , DateCol = new DateTime ( 2012 , 3 , 1 ) , TextCol = "qwer" , EnumCol = TestEnum . Val2 , NullableIntCol = 30 } ) ;
23
- db . Insert ( new TestType { Id = 4 , BoolCol = false , DateCol = new DateTime ( 2012 , 4 , 1 ) , TextCol = "qwer123" , EnumCol = TestEnum . Val3 , NullableIntCol = 40 } ) ;
21
+ db . Insert ( new TestType { Id = 1 , BoolCol = true , DateCol = new DateTime ( 2012 , 1 , 1 ) , TextCol = "asdf" , EnumCol = TestEnum . Val0 , NullableIntCol = 10 , TestType2ObjColId = 1 } ) ;
22
+ db . Insert ( new TestType { Id = 2 , BoolCol = true , DateCol = new DateTime ( 2012 , 2 , 1 ) , TextCol = "asdf123" , EnumCol = TestEnum . Val1 , NullableIntCol = null , TestType2ObjColId = 2 } ) ;
23
+ db . Insert ( new TestType { Id = 3 , BoolCol = false , DateCol = new DateTime ( 2012 , 3 , 1 ) , TextCol = "qwer" , EnumCol = TestEnum . Val2 , NullableIntCol = 30 , TestType2ObjColId = 3 } ) ;
24
+ db . Insert ( new TestType { Id = 4 , BoolCol = false , DateCol = new DateTime ( 2012 , 4 , 1 ) , TextCol = "qwer123" , EnumCol = TestEnum . Val3 , NullableIntCol = 40 , TestType2ObjColId = 4 } ) ;
25
+
26
+ db . DropAndCreateTable < TestType2 > ( ) ;
27
+ db . Insert ( new TestType2 { Id = 1 , BoolCol = true , DateCol = new DateTime ( 2012 , 4 , 1 ) , TextCol = "111" , EnumCol = TestEnum . Val3 , NullableIntCol = 10 , TestType2Name = "2.1" , TestType3ObjColId = 1 } ) ;
28
+ db . Insert ( new TestType2 { Id = 2 , BoolCol = false , DateCol = new DateTime ( 2012 , 4 , 1 ) , TextCol = "222" , EnumCol = TestEnum . Val3 , NullableIntCol = 20 , TestType2Name = "2.2" , TestType3ObjColId = 2 } ) ;
29
+ db . Insert ( new TestType2 { Id = 3 , BoolCol = true , DateCol = new DateTime ( 2012 , 4 , 1 ) , TextCol = "333" , EnumCol = TestEnum . Val3 , NullableIntCol = 30 , TestType2Name = "2.3" , TestType3ObjColId = 3 } ) ;
30
+ db . Insert ( new TestType2 { Id = 4 , BoolCol = false , DateCol = new DateTime ( 2012 , 4 , 1 ) , TextCol = "444" , EnumCol = TestEnum . Val3 , NullableIntCol = 40 , TestType2Name = "2.4" , TestType3ObjColId = 4 } ) ;
31
+
32
+
33
+ db . DropAndCreateTable < TestType3 > ( ) ;
34
+ db . Insert ( new TestType3 { Id = 1 , BoolCol = true , DateCol = new DateTime ( 2012 , 4 , 1 ) , TextCol = "111" , EnumCol = TestEnum . Val3 , NullableIntCol = 10 , TestType3Name = "3.1" , CustomInt = 100 } ) ;
35
+ db . Insert ( new TestType3 { Id = 2 , BoolCol = false , DateCol = new DateTime ( 2012 , 4 , 1 ) , TextCol = "222" , EnumCol = TestEnum . Val3 , NullableIntCol = 20 , TestType3Name = "3.2" , CustomInt = 200 } ) ;
36
+ db . Insert ( new TestType3 { Id = 3 , BoolCol = false , DateCol = new DateTime ( 2012 , 4 , 1 ) , TextCol = "222" , EnumCol = TestEnum . Val3 , NullableIntCol = 30 , TestType3Name = "3.3" , CustomInt = 300 } ) ;
37
+ db . Insert ( new TestType3 { Id = 4 , BoolCol = false , DateCol = new DateTime ( 2012 , 4 , 1 ) , TextCol = "222" , EnumCol = TestEnum . Val3 , NullableIntCol = 40 , TestType3Name = "3.4" , CustomInt = 400 } ) ;
24
38
}
25
39
Db = OpenDbConnection ( ) ;
26
40
}
@@ -338,6 +352,65 @@ public void Can_Select_using_expression_evaluated_to_constant()
338
352
CollectionAssert . AreEquivalent ( new [ ] { 1 , 3 , 4 } , target . Select ( t => t . Id ) . ToArray ( ) ) ;
339
353
}
340
354
355
+ [ Test ]
356
+ public void Can_Where_using_filter_with_nested_properties ( )
357
+ {
358
+ string filterText2 = "2.1" ;
359
+ string filterText3 = "3.3" ;
360
+ bool ? nullableTrue = true ;
361
+
362
+ var q = Db . From < TestType > ( ) .
363
+ Join < TestType2 > ( ) .
364
+ Where ( x => ( ! x . NullableBoolCol . HasValue || x . NullableBoolCol . Value ) && x . NullableIntCol . HasValue && x . TestType2ObjCol . BoolCol ) ;
365
+ var target = Db . Select ( q ) ;
366
+ Assert . AreEqual ( 2 , target . Count ) ;
367
+
368
+ q = Db . From < TestType > ( ) .
369
+ Join < TestType2 > ( ) .
370
+ Where ( x => x . TestType2ObjCol . BoolCol && x . DateCol != DateTime . MinValue ) ;
371
+ target = Db . Select ( q ) ;
372
+ Assert . AreEqual ( 2 , target . Count ) ;
373
+
374
+ q = Db . From < TestType > ( ) .
375
+ Join < TestType2 > ( ) .
376
+ Where ( x => x . TestType2ObjCol . BoolCol && x . TestType2ObjCol . BoolCol == nullableTrue &&
377
+ x . DateCol != DateTime . MinValue && x . TestType2ObjCol . TestType2Name == filterText2 ) ;
378
+ target = Db . Select ( q ) ;
379
+ Assert . AreEqual ( 1 , target . Count ) ;
380
+
381
+ var intValue = 300 ;
382
+ q = Db . From < TestType > ( ) .
383
+ Join < TestType2 > ( ) .
384
+ Join < TestType2 , TestType3 > ( ) .
385
+ Where ( x => ! x . NullableBoolCol . HasValue && x . TestType2ObjCol . BoolCol &&
386
+ x . TestType2ObjCol . TestType3ObjCol . TestType3Name == filterText3 &&
387
+ x . TestType2ObjCol . TestType3ObjCol . CustomInt == new CustomInt ( intValue ) ) ;
388
+ target = Db . Select ( q ) ;
389
+ Assert . AreEqual ( 1 , target . Count ) ;
390
+
391
+ q = Db . From < TestType > ( ) .
392
+ Join < TestType2 > ( ) .
393
+ Join < TestType2 , TestType3 > ( ) .
394
+ Where ( x => ! x . NullableBoolCol . HasValue && x . TestType2ObjCol . BoolCol &&
395
+ x . NullableIntCol == new CustomInt ( 10 ) ) .
396
+ GroupBy ( x => x . TestType2ObjCol . TestType3ObjCol . CustomInt ) .
397
+ Having ( x => ( Sql . Max ( x . TestType2ObjCol . TestType3ObjCol . CustomInt ) ?? 0 ) == new CustomInt ( 100 ) ) .
398
+ Select ( x => x . TestType2ObjCol . TestType3ObjCol . CustomInt ) ;
399
+ target = Db . Select ( q ) ;
400
+ Assert . AreEqual ( 1 , target . Count ) ;
401
+
402
+ q = Db . From < TestType > ( ) .
403
+ Join < TestType2 > ( ) .
404
+ Join < TestType2 , TestType3 > ( ) .
405
+ Where ( x => ! x . NullableBoolCol . HasValue && x . TestType2ObjCol . BoolCol &&
406
+ x . NullableIntCol == new CustomInt ( 10 ) ) .
407
+ GroupBy ( x => x . TestType2ObjCol . TestType3ObjCol . CustomInt ) .
408
+ Having ( x => ( Sql . Max ( x . TestType2ObjCol . TestType3ObjCol . CustomInt ) ?? 0 ) != 10 ) .
409
+ Select ( x => x . TestType2ObjCol . TestType3ObjCol . CustomInt ) ;
410
+ target = Db . Select ( q ) ;
411
+ Assert . AreEqual ( 1 , target . Count ) ;
412
+ }
413
+
341
414
private int MethodReturningInt ( int val )
342
415
{
343
416
return val ;
@@ -372,6 +445,10 @@ public class TestType
372
445
public TestEnum EnumCol { get ; set ; }
373
446
public TestType ComplexObjCol { get ; set ; }
374
447
public int ? NullableIntCol { get ; set ; }
448
+
449
+ [ ForeignKey ( typeof ( TestType2 ) ) ]
450
+ public int TestType2ObjColId { get ; set ; }
451
+ public TestType2 TestType2ObjCol { get ; set ; }
375
452
}
376
453
377
454
public class TestType2
@@ -384,5 +461,54 @@ public class TestType2
384
461
public TestEnum EnumCol { get ; set ; }
385
462
public TestType ComplexObjCol { get ; set ; }
386
463
public int ? NullableIntCol { get ; set ; }
464
+ public string TestType2Name { get ; set ; }
465
+
466
+ [ ForeignKey ( typeof ( TestType3 ) ) ]
467
+ public int TestType3ObjColId { get ; set ; }
468
+ public TestType3 TestType3ObjCol { get ; set ; }
469
+ }
470
+
471
+ public class TestType3
472
+ {
473
+ public int Id { get ; set ; }
474
+ public string TextCol { get ; set ; }
475
+ public bool BoolCol { get ; set ; }
476
+ public bool ? NullableBoolCol { get ; set ; }
477
+ public DateTime DateCol { get ; set ; }
478
+ public TestEnum EnumCol { get ; set ; }
479
+ public TestType3 ComplexObjCol { get ; set ; }
480
+ public int ? NullableIntCol { get ; set ; }
481
+ public string TestType3Name { get ; set ; }
482
+ public CustomInt CustomInt { get ; set ; }
483
+ }
484
+
485
+ /// <summary>
486
+ /// For testing VisitUnary with expression "u" that: u.Method != null (implicit conversion)
487
+ /// </summary>
488
+ public class CustomInt
489
+ {
490
+ private readonly int _value ;
491
+
492
+ public CustomInt ( int value )
493
+ {
494
+ _value = value ;
495
+ }
496
+
497
+ public int Value
498
+ {
499
+ get { return _value ; }
500
+ }
501
+
502
+
503
+ public static implicit operator int ( CustomInt s )
504
+ {
505
+ return s . Value ;
506
+ }
507
+
508
+ public static implicit operator CustomInt ( int s )
509
+ {
510
+ return new CustomInt ( s ) ;
511
+ }
512
+
387
513
}
388
514
}
0 commit comments