Tests.cs 33.8 KB
Newer Older
S
Sam Saffron 已提交
1 2 3
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
M
mgravell 已提交
4
using System.Linq;
5
using Dapper;
6 7
using System.Data.SqlServerCe;
using System.IO;
S
Sam Saffron 已提交
8 9
using System.Data;
using System.Collections;
S
Sam Saffron 已提交
10 11 12

namespace SqlMapper
{
S
Sam Saffron 已提交
13
    static class Assert
S
Sam Saffron 已提交
14
    {
S
Sam Saffron 已提交
15

16
        public static void IsEqualTo<T>(this T obj, T other)
S
Sam Saffron 已提交
17 18 19 20 21 22 23
        {
            if (!obj.Equals(other))
            {
                throw new ApplicationException(string.Format("{0} should be equals to {1}", obj, other));
            }
        }

24
        public static void IsSequenceEqualTo<T>(this IEnumerable<T> obj, IEnumerable<T> other)
S
Sam Saffron 已提交
25
        {
S
Sam Saffron 已提交
26
            if (!obj.SequenceEqual(other))
S
Sam Saffron 已提交
27
            {
S
Sam Saffron 已提交
28
                throw new ApplicationException(string.Format("{0} should be equals to {1}", obj, other));
S
Sam Saffron 已提交
29 30 31
            }
        }

S
Sam Saffron 已提交
32
        public static void IsFalse(this bool b)
S
Sam Saffron 已提交
33
        {
S
Sam Saffron 已提交
34
            if (b)
S
Sam Saffron 已提交
35
            {
S
Sam Saffron 已提交
36
                throw new ApplicationException("Expected false");
S
Sam Saffron 已提交
37 38 39
            }
        }

40 41
        public static void IsTrue(this bool b)
        {
S
Sam Saffron 已提交
42
            if (!b)
43 44 45 46 47
            {
                throw new ApplicationException("Expected true");
            }
        }

S
Sam Saffron 已提交
48 49 50 51 52 53 54
        public static void IsNull(this object obj)
        {
            if (obj != null)
            {
                throw new ApplicationException("Expected null");
            }
        }
S
Sam Saffron 已提交
55

S
Sam Saffron 已提交
56 57 58 59
    }

    class Tests
    {
60

S
Sam Saffron 已提交
61 62 63 64
        SqlConnection connection = Program.GetOpenConnection();

        public void SelectListInt()
        {
65
            connection.Query<int>("select 1 union all select 2 union all select 3")
66
              .IsSequenceEqualTo(new[] { 1, 2, 3 });
S
Sam Saffron 已提交
67
        }
M
mgravell 已提交
68 69 70 71
        public void SelectBinary()
        {
            connection.Query<byte[]>("select cast(1 as varbinary(4))").First().SequenceEqual(new byte[] {1});
        }
S
Sam Saffron 已提交
72 73
        public void PassInIntArray()
        {
74
            connection.Query<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[] { 1, 2, 3 }.AsEnumerable() })
75
             .IsSequenceEqualTo(new[] { 1, 2, 3 });
S
Sam Saffron 已提交
76
        }
S
Sam Saffron 已提交
77

78 79 80 81 82 83
        public void PassInEmptyIntArray()
        {
            connection.Query<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[0] })
             .IsSequenceEqualTo(new int[0]);
        }

84 85
        public void TestReadMultipleIntegersWithSplitOnAny()
        {
86
            connection.Query<int, int, int, Tuple<int, int, int>>(
87
                "select 1,2,3 union all select 4,5,6", Tuple.Create, splitOn: "*")
88
             .IsSequenceEqualTo(new[] { Tuple.Create(1, 2, 3), Tuple.Create(4, 5, 6) });
89
        }
S
Sam Saffron 已提交
90 91 92

        public void TestDoubleParam()
        {
93
            connection.Query<double>("select @d", new { d = 0.1d }).First()
94
                .IsEqualTo(0.1d);
S
Sam Saffron 已提交
95 96 97 98
        }

        public void TestBoolParam()
        {
99
            connection.Query<bool>("select @b", new { b = false }).First()
S
Sam Saffron 已提交
100
                .IsFalse();
S
Sam Saffron 已提交
101 102 103 104
        }

        public void TestStrings()
        {
105
            connection.Query<string>(@"select 'a' a union select 'b'")
106
                .IsSequenceEqualTo(new[] { "a", "b" });
S
Sam Saffron 已提交
107 108
        }

109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
        enum EnumParam : short
        {
            None, A, B
        }
        class EnumParamObject
        {
            public EnumParam A { get; set; }
            public EnumParam? B { get; set; }
            public EnumParam? C { get; set; }
        }
        public void TestEnumParams()
        {
            EnumParam a = EnumParam.A;
            EnumParam? b = EnumParam.B, c = null;
            var obj = connection.Query<EnumParamObject>("select @a as A, @b as B, @c as C",
                new { a, b, c }).Single();
            obj.A.IsEqualTo(EnumParam.A);
            obj.B.IsEqualTo(EnumParam.B);
            obj.C.IsEqualTo(null);
        }

S
Sam Saffron 已提交
130 131 132 133 134 135 136 137 138 139
        public class Dog
        {
            public int? Age { get; set; }
            public Guid Id { get; set; }
            public string Name { get; set; }
            public float? Weight { get; set; }

            public int IgnoredProperty { get { return 1; } }
        }

140 141 142
        public void TestExtraFields()
        {
            var guid = Guid.NewGuid();
143
            var dog = connection.Query<Dog>("select '' as Extra, 1 as Age, 0.1 as Name1 , Id = @id", new { Id = guid });
144 145 146 147 148 149 150 151 152 153 154 155

            dog.Count()
               .IsEqualTo(1);

            dog.First().Age
                .IsEqualTo(1);

            dog.First().Id
                .IsEqualTo(guid);
        }


156
        public void TestStrongType()
S
Sam Saffron 已提交
157
        {
158
            var guid = Guid.NewGuid();
159
            var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });
160

S
Sam Saffron 已提交
161
            dog.Count()
162
                .IsEqualTo(1);
S
Sam Saffron 已提交
163 164 165

            dog.First().Age
                .IsNull();
166 167

            dog.First().Id
168
                .IsEqualTo(guid);
S
Sam Saffron 已提交
169 170
        }

S
Sam Saffron 已提交
171 172
        public void TestSimpleNull()
        {
173
            connection.Query<DateTime?>("select null").First().IsNull();
S
Sam Saffron 已提交
174
        }
175

S
Sam Saffron 已提交
176 177
        public void TestExpando()
        {
178
            var rows = connection.Query("select 1 A, 2 B union all select 3, 4").ToList();
179

S
Sam Saffron 已提交
180
            ((int)rows[0].A)
181
                .IsEqualTo(1);
S
Sam Saffron 已提交
182 183

            ((int)rows[0].B)
184
                .IsEqualTo(2);
S
Sam Saffron 已提交
185 186

            ((int)rows[1].A)
187
                .IsEqualTo(3);
S
Sam Saffron 已提交
188 189

            ((int)rows[1].B)
190
                .IsEqualTo(4);
S
Sam Saffron 已提交
191
        }
S
Sam Saffron 已提交
192 193

        public void TestStringList()
S
Sam Saffron 已提交
194
        {
195 196
            connection.Query<string>("select * from (select 'a' as x union all select 'b' union all select 'c') as T where x in @strings", new { strings = new[] { "a", "b", "c" } })
                .IsSequenceEqualTo(new[] { "a", "b", "c" });
S
Sam Saffron 已提交
197

198 199
            connection.Query<string>("select * from (select 'a' as x union all select 'b' union all select 'c') as T where x in @strings", new { strings = new string[0] })
                   .IsSequenceEqualTo(new string[0]);
S
Sam Saffron 已提交
200 201
        }

S
Sam Saffron 已提交
202 203
        public void TestExecuteCommand()
        {
204
            connection.Execute(@"
S
Sam Saffron 已提交
205 206 207 208 209 210
    set nocount on 
    create table #t(i int) 
    set nocount off 
    insert #t 
    select @a a union all select @b 
    set nocount on 
211
    drop table #t", new { a = 1, b = 2 }).IsEqualTo(2);
S
Sam Saffron 已提交
212
        }
213 214 215
        public void TestExecuteCommandWithHybridParameters()
        {
            var p = new DynamicParameters(new { a = 1, b = 2 });
216
            p.Add("c", dbType: DbType.Int32, direction: ParameterDirection.Output);
217 218 219
            connection.Execute(@"set @c = @a + @b", p);
            p.Get<int>("@c").IsEqualTo(3);
        }
220 221 222 223 224 225 226 227
        public void TestExecuteMultipleCommand()
        {
            connection.Execute("create table #t(i int)");
            int tally = connection.Execute(@"insert #t (i) values(@a)", new[] { new { a = 1 }, new { a = 2 }, new { a = 3 }, new { a = 4 } });
            int sum = connection.Query<int>("select sum(i) from #t drop table #t").First();
            tally.IsEqualTo(4);
            sum.IsEqualTo(10);
        }
S
Sam Saffron 已提交
228

229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
        class Student
        {
            public string Name {get; set;}
            public int Age { get; set; }
        }

        public void TestExecuteMultipleCommandStrongType()
        {
            connection.Execute("create table #t(Name nvarchar(max), Age int)");
            int tally = connection.Execute(@"insert #t (Name,Age) values(@Name, @Age)", new List<Student> 
            {
                new Student{Age = 1, Name = "sam"},
                new Student{Age = 2, Name = "bob"}
            });
            int sum = connection.Query<int>("select sum(Age) from #t drop table #t").First();
            tally.IsEqualTo(2);
            sum.IsEqualTo(3);
        }

248 249 250 251 252 253 254 255 256
        public void TestExecuteMultipleCommandObjectArray()
        {
            connection.Execute("create table #t(i int)");
            int tally = connection.Execute(@"insert #t (i) values(@a)", new object[] { new { a = 1 }, new { a = 2 }, new { a = 3 }, new { a = 4 } });
            int sum = connection.Query<int>("select sum(i) from #t drop table #t").First();
            tally.IsEqualTo(4);
            sum.IsEqualTo(10);
        }

S
Sam Saffron 已提交
257
        public void TestMassiveStrings()
258
        {
S
Sam Saffron 已提交
259
            var str = new string('X', 20000);
260
            connection.Query<string>("select @a", new { a = str }).First()
261
                .IsEqualTo(str);
S
Sam Saffron 已提交
262 263
        }

264 265 266 267 268 269 270 271 272 273 274
        class TestObj
        {
            public int _internal;
            internal int Internal { set { _internal = value; } }

            public int _priv;
            internal int Priv { set { _priv = value; } }
        }

        public void TestSetInternal()
        {
275
            connection.Query<TestObj>("select 10 as [Internal]").First()._internal.IsEqualTo(10);
276 277 278 279
        }

        public void TestSetPrivate()
        {
280
            connection.Query<TestObj>("select 10 as [Priv]").First()._priv.IsEqualTo(10);
281 282
        }

283 284
        public void TestEnumeration()
        {
S
Sam Saffron 已提交
285 286 287 288
            var en = connection.Query<int>("select 1 as one union all select 2 as one", buffered: false);
            var i = en.GetEnumerator();
            i.MoveNext();

289 290 291
            bool gotException = false;
            try
            {
S
Sam Saffron 已提交
292
                var x = connection.Query<int>("select 1 as one", buffered: false).First();
293 294 295 296 297 298
            }
            catch (Exception)
            {
                gotException = true;
            }

S
Sam Saffron 已提交
299 300
            while (i.MoveNext())
            { }
301 302

            // should not exception, since enumertated
303
            en = connection.Query<int>("select 1 as one", buffered: false);
304 305 306 307 308 309

            gotException.IsTrue();
        }

        public void TestEnumerationDynamic()
        {
S
Sam Saffron 已提交
310 311 312 313
            var en = connection.Query("select 1 as one union all select 2 as one", buffered: false);
            var i = en.GetEnumerator();
            i.MoveNext();

314 315 316
            bool gotException = false;
            try
            {
S
Sam Saffron 已提交
317
                var x = connection.Query("select 1 as one", buffered: false).First();
318 319 320 321 322 323
            }
            catch (Exception)
            {
                gotException = true;
            }

S
Sam Saffron 已提交
324 325
            while (i.MoveNext())
            { }
326 327

            // should not exception, since enumertated
S
Sam Saffron 已提交
328
            en = connection.Query("select 1 as one", buffered: false);
329 330 331

            gotException.IsTrue();
        }
332

S
Sam Saffron 已提交
333

334
        class User
S
Sam Saffron 已提交
335 336 337 338
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
339
        class Post
S
Sam Saffron 已提交
340 341 342 343 344 345 346
        {
            public int Id { get; set; }
            public User Owner { get; set; }
            public string Content { get; set; }
        }
        public void TestMultiMap()
        {
S
Sam Saffron 已提交
347 348 349
            var createSql = @"
                create table #Users (Id int, Name varchar(20))
                create table #Posts (Id int, OwnerId int, Content varchar(20))
S
Sam Saffron 已提交
350

S
style  
Sam Saffron 已提交
351
                insert #Users values(99, 'Sam')
S
Sam Saffron 已提交
352 353
                insert #Users values(2, 'I am')

S
style  
Sam Saffron 已提交
354 355
                insert #Posts values(1, 99, 'Sams Post1')
                insert #Posts values(2, 99, 'Sams Post2')
S
Sam Saffron 已提交
356 357 358 359
                insert #Posts values(3, null, 'no ones post')
";
            connection.Execute(createSql);

360
            var sql =
S
style  
Sam Saffron 已提交
361 362 363 364
@"select * from #Posts p 
left join #Users u on u.Id = p.OwnerId 
Order by p.Id";

365
            var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post; }).ToList();
S
style  
Sam Saffron 已提交
366
            var p = data.First();
367

S
style  
Sam Saffron 已提交
368 369 370 371
            p.Content.IsEqualTo("Sams Post1");
            p.Id.IsEqualTo(1);
            p.Owner.Name.IsEqualTo("Sam");
            p.Owner.Id.IsEqualTo(99);
372 373 374 375 376 377 378

            data[2].Owner.IsNull();

            connection.Execute("drop table #Users drop table #Posts");
        }


379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423

        public void TestMultiMapGridReader()
        {
            var createSql = @"
                create table #Users (Id int, Name varchar(20))
                create table #Posts (Id int, OwnerId int, Content varchar(20))

                insert #Users values(99, 'Sam')
                insert #Users values(2, 'I am')

                insert #Posts values(1, 99, 'Sams Post1')
                insert #Posts values(2, 99, 'Sams Post2')
                insert #Posts values(3, null, 'no ones post')
";
            connection.Execute(createSql);

            var sql =
@"select p.*, u.Id, u.Name + '0' Name from #Posts p 
left join #Users u on u.Id = p.OwnerId 
Order by p.Id

select p.*, u.Id, u.Name + '1' Name from #Posts p 
left join #Users u on u.Id = p.OwnerId 
Order by p.Id
";

            var grid = connection.QueryMultiple(sql);

            for (int i = 0; i < 2; i++)
            {
                var data = grid.Read<Post, User, Post>((post, user) => { post.Owner = user; return post; }).ToList();
                var p = data.First();

                p.Content.IsEqualTo("Sams Post1");
                p.Id.IsEqualTo(1);
                p.Owner.Name.IsEqualTo("Sam" + i);
                p.Owner.Id.IsEqualTo(99);

                data[2].Owner.IsNull();
            }
            
            connection.Execute("drop table #Users drop table #Posts");

        }

424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
        public void TestMultiMapDynamic()
        {
            var createSql = @"
                create table #Users (Id int, Name varchar(20))
                create table #Posts (Id int, OwnerId int, Content varchar(20))

                insert #Users values(99, 'Sam')
                insert #Users values(2, 'I am')

                insert #Posts values(1, 99, 'Sams Post1')
                insert #Posts values(2, 99, 'Sams Post2')
                insert #Posts values(3, null, 'no ones post')
";
            connection.Execute(createSql);

            var sql =
@"select * from #Posts p 
left join #Users u on u.Id = p.OwnerId 
Order by p.Id";

444
            var data = connection.Query<dynamic, dynamic, dynamic>(sql, (post, user) => { post.Owner = user; return post; }).ToList();
445 446 447 448 449 450 451 452 453 454 455
            var p = data.First();

            // hairy extension method support for dynamics
            ((string)p.Content).IsEqualTo("Sams Post1");
            ((int)p.Id).IsEqualTo(1);
            ((string)p.Owner.Name).IsEqualTo("Sam");
            ((int)p.Owner.Id).IsEqualTo(99);

            ((object)data[2].Owner).IsNull();

            connection.Execute("drop table #Users drop table #Posts");
S
Sam Saffron 已提交
456
        }
457

M
mgravell 已提交
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
        class Product
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public Category Category { get; set; }
        }
        class Category
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
        public void TestMultiMapWithSplit() // http://stackoverflow.com/q/6056778/23354
        {
            var sql = @"select 1 as id, 'abc' as name, 2 as id, 'def' as name";
            var product = connection.Query<Product, Category, Product>(sql, (prod, cat) =>
            {
                prod.Category = cat;
                return prod;
            }).First();
            // assertions
            product.Id.IsEqualTo(1);
            product.Name.IsEqualTo("abc");
            product.Category.Id.IsEqualTo(2);
            product.Category.Name.IsEqualTo("def");
        }
M
mgravell 已提交
483 484 485 486 487
        public void TestFieldsAndPrivates()
        {
            var data = connection.Query<TestFieldCaseAndPrivatesEntity>(
                @"select a=1,b=2,c=3,d=4,f='5'").Single();

488

M
mgravell 已提交
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
            data.a.IsEqualTo(1);
            data.GetB().IsEqualTo(2);
            data.c.IsEqualTo(3);
            data.GetD().IsEqualTo(4);
            data.e.IsEqualTo(5);


        }

        private class TestFieldCaseAndPrivatesEntity
        {
            public int a { get; set; }
            private int b { get; set; }
            public int GetB() { return b; }
            public int c = 0;
            private int d = 0;
            public int GetD() { return d; }
            public int e { get; set; }
            private string f
            {
                get { return e.ToString(); }
                set { e = int.Parse(value); }
            }
        }
M
mgravell 已提交
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528

        public void TestMultiReaderBasic()
        {
            var sql = @"select 1 as Id union all select 2 as Id     select 'abc' as name   select 1 as Id union all select 2 as Id";
            int i, j;
            string s;
            using (var multi = connection.QueryMultiple(sql))
            {
                i = multi.Read<int>().First();
                s = multi.Read<string>().Single();
                j = multi.Read<int>().Sum();
            }
            Assert.IsEqualTo(i, 1);
            Assert.IsEqualTo(s, "abc");
            Assert.IsEqualTo(j, 3);
        }
S
Sam Saffron 已提交
529 530
        public void TestMultiMappingVariations()
        {
S
Sam Saffron 已提交
531
            var sql = @"select 1 as Id, 'a' as Content, 2 as Id, 'b' as Content, 3 as Id, 'c' as Content, 4 as Id, 'd' as Content, 5 as Id, 'e' as Content";
532 533

            var order = connection.Query<dynamic, dynamic, dynamic, dynamic>(sql, (o, owner, creator) => { o.Owner = owner; o.Creator = creator; return o; }).First();
S
Sam Saffron 已提交
534 535 536 537 538 539 540 541

            Assert.IsEqualTo(order.Id, 1);
            Assert.IsEqualTo(order.Content, "a");
            Assert.IsEqualTo(order.Owner.Id, 2);
            Assert.IsEqualTo(order.Owner.Content, "b");
            Assert.IsEqualTo(order.Creator.Id, 3);
            Assert.IsEqualTo(order.Creator.Content, "c");

542 543 544 545 546 547 548
            order = connection.Query<dynamic, dynamic, dynamic, dynamic, dynamic>(sql, (o, owner, creator, address) =>
            {
                o.Owner = owner;
                o.Creator = creator;
                o.Owner.Address = address;
                return o;
            }).First();
S
Sam Saffron 已提交
549 550 551 552 553 554 555 556 557 558

            Assert.IsEqualTo(order.Id, 1);
            Assert.IsEqualTo(order.Content, "a");
            Assert.IsEqualTo(order.Owner.Id, 2);
            Assert.IsEqualTo(order.Owner.Content, "b");
            Assert.IsEqualTo(order.Creator.Id, 3);
            Assert.IsEqualTo(order.Creator.Content, "c");
            Assert.IsEqualTo(order.Owner.Address.Id, 4);
            Assert.IsEqualTo(order.Owner.Address.Content, "d");

559
            order = connection.Query<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic>(sql, (a, b, c, d, e) => { a.B = b; a.C = c; a.C.D = d; a.E = e; return a; }).First();
S
Sam Saffron 已提交
560 561 562 563 564 565 566 567 568 569 570

            Assert.IsEqualTo(order.Id, 1);
            Assert.IsEqualTo(order.Content, "a");
            Assert.IsEqualTo(order.B.Id, 2);
            Assert.IsEqualTo(order.B.Content, "b");
            Assert.IsEqualTo(order.C.Id, 3);
            Assert.IsEqualTo(order.C.Content, "c");
            Assert.IsEqualTo(order.C.D.Id, 4);
            Assert.IsEqualTo(order.C.D.Content, "d");
            Assert.IsEqualTo(order.E.Id, 5);
            Assert.IsEqualTo(order.E.Content, "e");
S
Sam Saffron 已提交
571 572 573

        }

574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595
        class InheritanceTest1
        {
            public string Base1 { get; set; }
            public string Base2 { get; private set; }
        }

        class InheritanceTest2 : InheritanceTest1
        {
            public string Derived1 { get; set; }
            public string Derived2 { get; private set; }
        }

        public void TestInheritance()
        {
            // Test that inheritance works.
            var list = connection.Query<InheritanceTest2>("select 'One' as Derived1, 'Two' as Derived2, 'Three' as Base1, 'Four' as Base2");
            list.First().Derived1.IsEqualTo("One");
            list.First().Derived2.IsEqualTo("Two");
            list.First().Base1.IsEqualTo("Three");
            list.First().Base2.IsEqualTo("Four");
        }

596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619

        public class PostCE
        {
            public int ID { get; set; }
            public string Title { get; set; }
            public string Body { get; set; }

            public AuthorCE Author { get; set; }
        }

        public class AuthorCE
        {
            public int ID { get; set; }
            public string Name { get; set; }
        }

        public void MultiRSSqlCE()
        {
            if (File.Exists("Test.sdf"))
                File.Delete("Test.sdf");

            var cnnStr = "Data Source = Test.sdf;";
            var engine = new SqlCeEngine(cnnStr);
            engine.CreateDatabase();
620

621 622 623 624 625 626 627 628 629 630 631
            using (var cnn = new SqlCeConnection(cnnStr))
            {
                cnn.Open();

                cnn.Execute("create table Posts (ID int, Title nvarchar(50), Body nvarchar(50), AuthorID int)");
                cnn.Execute("create table Authors (ID int, Name nvarchar(50))");

                cnn.Execute("insert Posts values (1,'title','body',1)");
                cnn.Execute("insert Posts values(2,'title2','body2',null)");
                cnn.Execute("insert Authors values(1,'sam')");

632
                var data = cnn.Query<PostCE, AuthorCE, PostCE>(@"select * from Posts p left join Authors a on a.ID = p.AuthorID", (post, author) => { post.Author = author; return post; }).ToList();
633
                var firstPost = data.First();
S
Sam Saffron 已提交
634 635 636
                firstPost.Title.IsEqualTo("title");
                firstPost.Author.Name.IsEqualTo("sam");
                data[1].Author.IsNull();
637 638 639
                cnn.Close();
            }
        }
S
Sam Saffron 已提交
640 641

        enum TestEnum : byte
642 643
        {
            Bla = 1
S
Sam Saffron 已提交
644 645 646 647 648
        }
        class TestEnumClass
        {
            public TestEnum? EnumEnum { get; set; }
        }
M
mgravell 已提交
649 650 651 652
        class TestEnumClassNoNull
        {
            public TestEnum EnumEnum { get; set; }
        }
S
Sam Saffron 已提交
653
        public void TestEnumWeirdness()
S
Sam Saffron 已提交
654
        {
M
mgravell 已提交
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
            connection.Query<TestEnumClass>("select null as [EnumEnum]").First().EnumEnum.IsEqualTo(null);
            connection.Query<TestEnumClass>("select cast(1 as tinyint) as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
        }
        void Foo()
        {
            string s = "Bla";
            var obj = new TestEnumClassNoNull();
            obj.EnumEnum = (TestEnum)Enum.Parse(typeof(TestEnum), s, true);
        }
        public void TestEnumStrings()
        {
            connection.Query<TestEnumClassNoNull>("select 'BLA' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
            connection.Query<TestEnumClassNoNull>("select 'bla' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);

            connection.Query<TestEnumClass>("select 'BLA' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
            connection.Query<TestEnumClass>("select 'bla' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
S
Sam Saffron 已提交
671 672
        }

S
Sam Saffron 已提交
673 674 675
        public void TestSupportForParamDictionary()
        {
            var p = new DynamicParameters();
676 677 678
            p.Add("name", "bob");
            p.Add("age", dbType: DbType.Int32, direction: ParameterDirection.Output);

S
Sam Saffron 已提交
679 680
            connection.Query<string>("set @age = 11 select @name", p).First().IsEqualTo("bob");

681
            p.Get<int>("age").IsEqualTo(11);
S
Sam Saffron 已提交
682 683
        }

S
Sam Saffron 已提交
684 685 686 687

        public void TestProcSupport()
        {
            var p = new DynamicParameters();
688 689 690
            p.Add("a", 11);
            p.Add("b", dbType: DbType.Int32, direction: ParameterDirection.Output);
            p.Add("c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
S
Sam Saffron 已提交
691 692 693 694 695 696 697 698 699 700 701 702

            connection.Execute(@"create proc #TestProc 
	@a int,
	@b int output
as 
begin
	set @b = 999
	select 1111
	return @a
end");
            connection.Query<int>("#TestProc", p, commandType: CommandType.StoredProcedure).First().IsEqualTo(1111);

703 704
            p.Get<int>("c").IsEqualTo(11);
            p.Get<int>("b").IsEqualTo(999);
S
Sam Saffron 已提交
705 706 707

        }

M
mgravell 已提交
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
        public void TestDbString()
        {
            var obj = connection.Query("select datalength(@a) as a, datalength(@b) as b, datalength(@c) as c, datalength(@d) as d, datalength(@e) as e, datalength(@f) as f",
                new
                {
                    a = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true },
                    b = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = false },
                    c = new DbString { Value = "abcde", IsFixedLength = false, Length = 10, IsAnsi = true },
                    d = new DbString { Value = "abcde", IsFixedLength = false, Length = 10, IsAnsi = false },
                    e = new DbString { Value = "abcde", IsAnsi = true },
                    f = new DbString { Value = "abcde", IsAnsi = false },
                }).First();
            ((int)obj.a).IsEqualTo(10);
            ((int)obj.b).IsEqualTo(20);
            ((int)obj.c).IsEqualTo(5);
            ((int)obj.d).IsEqualTo(10);
            ((int)obj.e).IsEqualTo(5);
            ((int)obj.f).IsEqualTo(10);
        }

S
Sam Saffron 已提交
728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
        class Person
        {
            public int PersonId { get; set; }
            public string Name { get; set; }
        }

        class Address
        {
            public int AddressId { get; set; }
            public string Name { get; set; }
            public int PersonId { get; set; }
        }

        class Extra
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }

        public void TestFlexibleMultiMapping()
        {
749
            var sql =
S
Sam Saffron 已提交
750 751 752 753 754
@"select 
    1 as PersonId, 'bob' as Name, 
    2 as AddressId, 'abc street' as Name, 1 as PersonId,
    3 as Id, 'fred' as Name
    ";
755 756
            var personWithAddress = connection.Query<Person, Address, Extra, Tuple<Person, Address, Extra>>
                (sql, (p, a, e) => Tuple.Create(p, a, e), splitOn: "AddressId,Id").First();
S
Sam Saffron 已提交
757 758 759 760 761 762 763 764 765 766 767

            personWithAddress.Item1.PersonId.IsEqualTo(1);
            personWithAddress.Item1.Name.IsEqualTo("bob");
            personWithAddress.Item2.AddressId.IsEqualTo(2);
            personWithAddress.Item2.Name.IsEqualTo("abc street");
            personWithAddress.Item2.PersonId.IsEqualTo(1);
            personWithAddress.Item3.Id.IsEqualTo(3);
            personWithAddress.Item3.Name.IsEqualTo("fred");

        }

768 769 770 771 772 773 774 775

        public void TestFastExpandoSupportsIDictionary()
        {
            var row = connection.Query("select 1 A, 'two' B").First() as IDictionary<string, object>;
            row["A"].IsEqualTo(1);
            row["B"].IsEqualTo("two");
        }

S
Sam Saffron 已提交
776 777 778 779

        class PrivateDan
        {
            public int Shadow { get; set; }
780 781 782
            private string ShadowInDB
            {
                set
S
Sam Saffron 已提交
783
                {
784
                    Shadow = value == "one" ? 1 : 0;
S
Sam Saffron 已提交
785 786 787 788 789 790 791
                }
            }
        }
        public void TestDapperSetsPrivates()
        {
            connection.Query<PrivateDan>("select 'one' ShadowInDB").First().Shadow.IsEqualTo(1);
        }
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820


        class IntDynamicParam : Dapper.SqlMapper.IDynamicParameters
        {
            IEnumerable<int> numbers;
            public IntDynamicParam(IEnumerable<int> numbers)
            {
                this.numbers = numbers;
            }

            public void AddParameters(IDbCommand command)
            {
                var sqlCommand = (SqlCommand)command;
                sqlCommand.CommandType = CommandType.StoredProcedure;

                List<Microsoft.SqlServer.Server.SqlDataRecord> number_list = new List<Microsoft.SqlServer.Server.SqlDataRecord>();

                // Create an SqlMetaData object that describes our table type.
                Microsoft.SqlServer.Server.SqlMetaData[] tvp_definition = { new Microsoft.SqlServer.Server.SqlMetaData("n", SqlDbType.Int) };

                foreach (int n in numbers)
                {
                    // Create a new record, using the metadata array above.
                    Microsoft.SqlServer.Server.SqlDataRecord rec = new Microsoft.SqlServer.Server.SqlDataRecord(tvp_definition);
                    rec.SetInt32(0, n);    // Set the value.
                    number_list.Add(rec);      // Add it to the list.
                }

                // Add the table parameter.
821
                var p = sqlCommand.Parameters.Add("ints", SqlDbType.Structured);
822 823 824
                p.Direction = ParameterDirection.Input;
                p.TypeName = "int_list_type";
                p.Value = number_list;
825

826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855
            }
        }

        // SQL Server specific test to demonstrate TVP 
        public void TestTVP()
        {
            try
            {
                connection.Execute("CREATE TYPE int_list_type AS TABLE (n int NOT NULL PRIMARY KEY)");
                connection.Execute("CREATE PROC get_ints @ints int_list_type READONLY AS select * from @ints");

                var nums = connection.Query<int>("get_ints", new IntDynamicParam(new int[] { 1, 2, 3 })).ToList();
                nums[0].IsEqualTo(1);
                nums[1].IsEqualTo(2);
                nums[2].IsEqualTo(3);
                nums.Count.IsEqualTo(3);

            }
            finally
            {
                try
                {
                    connection.Execute("DROP PROC get_ints");
                }
                finally
                {
                    connection.Execute("DROP TYPE int_list_type");
                }
            }
        }
856

M
mgravell 已提交
857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880
        class Parent
        {
            public int Id { get; set; }
            public readonly List<Child> Children = new List<Child>();
        }
        class Child
        {
            public int Id { get; set; }
        }
        public void ParentChildIdentityAssociations()
        {
            var lookup = new Dictionary<int, Parent>();
            var parents = connection.Query<Parent, Child, Parent>(@"select 1 as [Id], 1 as [Id] union all select 1,2 union all select 2,3 union all select 1,4 union all select 3,5",
                (parent, child) =>
                {
                    Parent found;
                    if (!lookup.TryGetValue(parent.Id, out found))
                    {
                        lookup.Add(parent.Id, found = parent);
                    }
                    found.Children.Add(child);
                    return found;
                }).Distinct().ToDictionary(p => p.Id);
            parents.Count().IsEqualTo(3);
881
            parents[1].Children.Select(c => c.Id).SequenceEqual(new[] { 1, 2, 4 }).IsTrue();
M
mgravell 已提交
882 883 884 885
            parents[2].Children.Select(c => c.Id).SequenceEqual(new[] { 3 }).IsTrue();
            parents[3].Children.Select(c => c.Id).SequenceEqual(new[] { 5 }).IsTrue();
        }

886

S
Sam Saffron 已提交
887 888
        /* TODO:
         * 
S
Sam Saffron 已提交
889 890 891 892 893 894 895 896
        public void TestMagicParam()
        {
            // magic params allow you to pass in single params without using an anon class
            // this test fails for now, but I would like to support a single param by parsing the sql with regex and remapping. 

            var first = connection.Query("select @a as a", 1).First();
            Assert.IsEqualTo(first.a, 1);
        }
S
Sam Saffron 已提交
897
         * */
S
Sam Saffron 已提交
898

899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921
        class WithBizarreData
        {
            public GenericUriParser Foo { get; set; }
            public int Bar { get; set; }
        }
        public void TestUnexpectedDataMessage()
        {
            string msg = null;
            try {
                connection.Query<int>("select count(1) where 1 = @Foo", new WithBizarreData { Foo = new GenericUriParser(GenericUriParserOptions.Default), Bar = 23 }).First();

            } catch(Exception ex)
            {
                msg = ex.Message;
            }
            msg.IsEqualTo("The member Foo of type System.GenericUriParser cannot be used as a parameter value");
        }
        public void TestUnexpectedButFilteredDataMessage()
        {
            int i = connection.Query<int>("select @Bar", new WithBizarreData { Foo = new GenericUriParser(GenericUriParserOptions.Default), Bar = 23 }).Single();

            i.IsEqualTo(23);
        }
M
mgravell 已提交
922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960

        class WithCharValue
        {
            public char Value { get; set; }
            public char? ValueNullable { get; set; }
        }
        public void TestCharInputAndOutput()
        {
            const char test = '〠';
            char c = connection.Query<char>("select @c", new { c = test }).Single();

            c.IsEqualTo(test);

            var obj = connection.Query<WithCharValue>("select @Value as Value", new WithCharValue { Value = c }).Single();

            obj.Value.IsEqualTo(test);
        }
        public void TestNullableCharInputAndOutputNonNull()
        {
            char? test = '〠';
            char? c = connection.Query<char?>("select @c", new { c = test }).Single();

            c.IsEqualTo(test);

            var obj = connection.Query<WithCharValue>("select @ValueNullable as ValueNullable", new WithCharValue { ValueNullable = c }).Single();

            obj.ValueNullable.IsEqualTo(test);
        }
        public void TestNullableCharInputAndOutputNull()
        {
            char? test = null;
            char? c = connection.Query<char?>("select @c", new { c = test }).Single();

            c.IsEqualTo(test);

            var obj = connection.Query<WithCharValue>("select @ValueNullable as ValueNullable", new WithCharValue { ValueNullable = c }).Single();

            obj.ValueNullable.IsEqualTo(test);
        }
961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980
        public void TestInvalidSplitCausesNiceError()
        {
            try
            {
                connection.Query<User, User, User>("select 1 A, 2 B, 3 C", (x, y) => x);
            }
            catch (ArgumentException)
            { 
                // expecting an app exception due to multi mapping being bodged 
            }

            try
            {
                connection.Query<dynamic, dynamic, dynamic>("select 1 A, 2 B, 3 C", (x, y) => x);
            }
            catch (ArgumentException)
            {
                // expecting an app exception due to multi mapping being bodged 
            }
        }
S
Sam Saffron 已提交
981 982
    }
}