PageRenderTime 55ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/Tests/Tests.cs

https://github.com/jomit/dapper-dot-net
C# | 2315 lines | 1944 code | 328 blank | 43 comment | 14 complexity | 3afce8868624876fe516b0ea2def52c9 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. //#define POSTGRESQL // uncomment to run postgres tests
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Data.SqlClient;
  5. using System.Linq;
  6. using Dapper;
  7. using System.Data.SqlServerCe;
  8. using System.IO;
  9. using System.Data;
  10. using System.Collections;
  11. using System.Reflection;
  12. using System.Dynamic;
  13. using System.ComponentModel;
  14. using Microsoft.CSharp.RuntimeBinder;
  15. #if POSTGRESQL
  16. using Npgsql;
  17. #endif
  18. namespace SqlMapper
  19. {
  20. class Tests
  21. {
  22. SqlConnection connection = Program.GetOpenConnection();
  23. public class AbstractInheritance
  24. {
  25. public abstract class Order
  26. {
  27. internal int Internal { get; set; }
  28. protected int Protected { get; set; }
  29. public int Public { get; set; }
  30. public int ProtectedVal { get { return Protected; } }
  31. }
  32. public class ConcreteOrder : Order
  33. {
  34. public int Concrete { get; set; }
  35. }
  36. }
  37. class UserWithConstructor
  38. {
  39. public UserWithConstructor(int id, string name)
  40. {
  41. Ident = id;
  42. FullName = name;
  43. }
  44. public int Ident { get; set; }
  45. public string FullName { get; set; }
  46. }
  47. class PostWithConstructor
  48. {
  49. public PostWithConstructor(int id, int ownerid, string content)
  50. {
  51. Ident = id;
  52. FullContent = content;
  53. }
  54. public int Ident { get; set; }
  55. public UserWithConstructor Owner { get; set; }
  56. public string FullContent { get; set; }
  57. public Comment Comment { get; set; }
  58. }
  59. public void TestMultiMapWithConstructor()
  60. {
  61. var createSql = @"
  62. create table #Users (Id int, Name varchar(20))
  63. create table #Posts (Id int, OwnerId int, Content varchar(20))
  64. insert #Users values(99, 'Sam')
  65. insert #Users values(2, 'I am')
  66. insert #Posts values(1, 99, 'Sams Post1')
  67. insert #Posts values(2, 99, 'Sams Post2')
  68. insert #Posts values(3, null, 'no ones post')";
  69. connection.Execute(createSql);
  70. string sql = @"select * from #Posts p
  71. left join #Users u on u.Id = p.OwnerId
  72. Order by p.Id";
  73. PostWithConstructor[] data = connection.Query<PostWithConstructor, UserWithConstructor, PostWithConstructor>(sql, (post, user) => { post.Owner = user; return post;}).ToArray();
  74. var p = data.First();
  75. p.FullContent.IsEqualTo("Sams Post1");
  76. p.Ident.IsEqualTo(1);
  77. p.Owner.FullName.IsEqualTo("Sam");
  78. p.Owner.Ident.IsEqualTo(99);
  79. data[2].Owner.IsNull();
  80. connection.Execute("drop table #Users drop table #Posts");
  81. }
  82. class MultipleConstructors
  83. {
  84. public MultipleConstructors()
  85. {
  86. }
  87. public MultipleConstructors(int a, string b)
  88. {
  89. A = a + 1;
  90. B = b + "!";
  91. }
  92. public int A { get; set; }
  93. public string B { get; set; }
  94. }
  95. public void TestMultipleConstructors()
  96. {
  97. MultipleConstructors mult = connection.Query<MultipleConstructors>("select 0 A, 'Dapper' b").First();
  98. mult.A.IsEqualTo(0);
  99. mult.B.IsEqualTo("Dapper");
  100. }
  101. class ConstructorsWithAccessModifiers
  102. {
  103. private ConstructorsWithAccessModifiers()
  104. {
  105. }
  106. public ConstructorsWithAccessModifiers(int a, string b)
  107. {
  108. A = a + 1;
  109. B = b + "!";
  110. }
  111. public int A { get; set; }
  112. public string B { get; set; }
  113. }
  114. public void TestConstructorsWithAccessModifiers()
  115. {
  116. ConstructorsWithAccessModifiers value = connection.Query<ConstructorsWithAccessModifiers>("select 0 A, 'Dapper' b").First();
  117. value.A.IsEqualTo(1);
  118. value.B.IsEqualTo("Dapper!");
  119. }
  120. class NoDefaultConstructor
  121. {
  122. public NoDefaultConstructor(int a1, int? b1, float f1, string s1, Guid G1)
  123. {
  124. A = a1;
  125. B = b1;
  126. F = f1;
  127. S = s1;
  128. G = G1;
  129. }
  130. public int A { get; set; }
  131. public int? B { get; set; }
  132. public float F { get; set; }
  133. public string S { get; set; }
  134. public Guid G { get; set; }
  135. }
  136. public void TestNoDefaultConstructor()
  137. {
  138. var guid = Guid.NewGuid();
  139. NoDefaultConstructor nodef = connection.Query<NoDefaultConstructor>("select CAST(NULL AS integer) A1, CAST(NULL AS integer) b1, CAST(NULL AS real) f1, 'Dapper' s1, G1 = @id", new { Id = guid }).First();
  140. nodef.A.IsEqualTo(0);
  141. nodef.B.IsEqualTo(null);
  142. nodef.F.IsEqualTo(0);
  143. nodef.S.IsEqualTo("Dapper");
  144. nodef.G.IsEqualTo(guid);
  145. }
  146. class NoDefaultConstructorWithChar
  147. {
  148. public NoDefaultConstructorWithChar(char c1, char? c2, char? c3)
  149. {
  150. Char1 = c1;
  151. Char2 = c2;
  152. Char3 = c3;
  153. }
  154. public char Char1 { get; set; }
  155. public char? Char2 { get; set; }
  156. public char? Char3 { get; set; }
  157. }
  158. public void TestNoDefaultConstructorWithChar()
  159. {
  160. const char c1 = 'ą';
  161. const char c3 = 'ó';
  162. NoDefaultConstructorWithChar nodef = connection.Query<NoDefaultConstructorWithChar>("select @c1 c1, @c2 c2, @c3 c3", new { c1 = c1, c2 = (char?)null, c3 = c3 }).First();
  163. nodef.Char1.IsEqualTo(c1);
  164. nodef.Char2.IsEqualTo(null);
  165. nodef.Char3.IsEqualTo(c3);
  166. }
  167. class NoDefaultConstructorWithEnum
  168. {
  169. public NoDefaultConstructorWithEnum(ShortEnum e1, ShortEnum? n1, ShortEnum? n2)
  170. {
  171. E = e1;
  172. NE1 = n1;
  173. NE2 = n2;
  174. }
  175. public ShortEnum E { get; set; }
  176. public ShortEnum? NE1 { get; set; }
  177. public ShortEnum? NE2 { get; set; }
  178. }
  179. public void TestNoDefaultConstructorWithEnum()
  180. {
  181. NoDefaultConstructorWithEnum nodef = connection.Query<NoDefaultConstructorWithEnum>("select cast(2 as smallint) E1, cast(5 as smallint) n1, cast(null as smallint) n2").First();
  182. nodef.E.IsEqualTo(ShortEnum.Two);
  183. nodef.NE1.IsEqualTo(ShortEnum.Five);
  184. nodef.NE2.IsEqualTo(null);
  185. }
  186. class NoDefaultConstructorWithBinary
  187. {
  188. public System.Data.Linq.Binary Value { get; set; }
  189. public int Ynt { get; set; }
  190. public NoDefaultConstructorWithBinary(System.Data.Linq.Binary val)
  191. {
  192. Value = val;
  193. }
  194. }
  195. public void TestNoDefaultConstructorBinary()
  196. {
  197. byte[] orig = new byte[20];
  198. new Random(123456).NextBytes(orig);
  199. var input = new System.Data.Linq.Binary(orig);
  200. var output = connection.Query<NoDefaultConstructorWithBinary>("select @input as val", new { input }).First().Value;
  201. output.ToArray().IsSequenceEqualTo(orig);
  202. }
  203. // http://stackoverflow.com/q/8593871
  204. public void TestAbstractInheritance()
  205. {
  206. var order = connection.Query<AbstractInheritance.ConcreteOrder>("select 1 Internal,2 Protected,3 [Public],4 Concrete").First();
  207. order.Internal.IsEqualTo(1);
  208. order.ProtectedVal.IsEqualTo(2);
  209. order.Public.IsEqualTo(3);
  210. order.Concrete.IsEqualTo(4);
  211. }
  212. public void TestListOfAnsiStrings()
  213. {
  214. var results = connection.Query<string>("select * from (select 'a' str union select 'b' union select 'c') X where str in @strings",
  215. new { strings = new[] { new DbString { IsAnsi = true, Value = "a" }, new DbString { IsAnsi = true, Value = "b" } } }).ToList();
  216. results[0].IsEqualTo("a");
  217. results[1].IsEqualTo("b");
  218. }
  219. public void TestNullableGuidSupport()
  220. {
  221. var guid = connection.Query<Guid?>("select null").First();
  222. guid.IsNull();
  223. guid = Guid.NewGuid();
  224. var guid2 = connection.Query<Guid?>("select @guid", new { guid }).First();
  225. guid.IsEqualTo(guid2);
  226. }
  227. public void TestNonNullableGuidSupport()
  228. {
  229. var guid = Guid.NewGuid();
  230. var guid2 = connection.Query<Guid?>("select @guid", new { guid }).First();
  231. Assert.IsTrue(guid == guid2);
  232. }
  233. struct Car
  234. {
  235. public enum TrapEnum : int
  236. {
  237. A = 1,
  238. B = 2
  239. }
  240. #pragma warning disable 0649
  241. public string Name;
  242. #pragma warning restore 0649
  243. public int Age { get; set; }
  244. public TrapEnum Trap { get; set; }
  245. }
  246. public void TestStructs()
  247. {
  248. var car = connection.Query<Car>("select 'Ford' Name, 21 Age, 2 Trap").First();
  249. car.Age.IsEqualTo(21);
  250. car.Name.IsEqualTo("Ford");
  251. ((int)car.Trap).IsEqualTo(2);
  252. }
  253. public void SelectListInt()
  254. {
  255. connection.Query<int>("select 1 union all select 2 union all select 3")
  256. .IsSequenceEqualTo(new[] { 1, 2, 3 });
  257. }
  258. public void SelectBinary()
  259. {
  260. connection.Query<byte[]>("select cast(1 as varbinary(4))").First().SequenceEqual(new byte[] { 1 });
  261. }
  262. public void PassInIntArray()
  263. {
  264. 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() })
  265. .IsSequenceEqualTo(new[] { 1, 2, 3 });
  266. }
  267. public void PassInEmptyIntArray()
  268. {
  269. 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] })
  270. .IsSequenceEqualTo(new int[0]);
  271. }
  272. public void TestSchemaChanged()
  273. {
  274. connection.Execute("create table #dog(Age int, Name nvarchar(max)) insert #dog values(1, 'Alf')");
  275. var d = connection.Query<Dog>("select * from #dog").Single();
  276. d.Name.IsEqualTo("Alf");
  277. d.Age.IsEqualTo(1);
  278. connection.Execute("alter table #dog drop column Name");
  279. d = connection.Query<Dog>("select * from #dog").Single();
  280. d.Name.IsNull();
  281. d.Age.IsEqualTo(1);
  282. connection.Execute("drop table #dog");
  283. }
  284. public void TestSchemaChangedMultiMap()
  285. {
  286. connection.Execute("create table #dog(Age int, Name nvarchar(max)) insert #dog values(1, 'Alf')");
  287. var tuple = connection.Query<Dog, Dog, Tuple<Dog, Dog>>("select * from #dog d1 join #dog d2 on 1=1", (d1, d2) => Tuple.Create(d1, d2), splitOn: "Age").Single();
  288. tuple.Item1.Name.IsEqualTo("Alf");
  289. tuple.Item1.Age.IsEqualTo(1);
  290. tuple.Item2.Name.IsEqualTo("Alf");
  291. tuple.Item2.Age.IsEqualTo(1);
  292. connection.Execute("alter table #dog drop column Name");
  293. tuple = connection.Query<Dog, Dog, Tuple<Dog, Dog>>("select * from #dog d1 join #dog d2 on 1=1", (d1, d2) => Tuple.Create(d1, d2), splitOn: "Age").Single();
  294. tuple.Item1.Name.IsNull();
  295. tuple.Item1.Age.IsEqualTo(1);
  296. tuple.Item2.Name.IsNull();
  297. tuple.Item2.Age.IsEqualTo(1);
  298. connection.Execute("drop table #dog");
  299. }
  300. public void TestReadMultipleIntegersWithSplitOnAny()
  301. {
  302. connection.Query<int, int, int, Tuple<int, int, int>>(
  303. "select 1,2,3 union all select 4,5,6", Tuple.Create, splitOn: "*")
  304. .IsSequenceEqualTo(new[] { Tuple.Create(1, 2, 3), Tuple.Create(4, 5, 6) });
  305. }
  306. public void TestDoubleParam()
  307. {
  308. connection.Query<double>("select @d", new { d = 0.1d }).First()
  309. .IsEqualTo(0.1d);
  310. }
  311. public void TestBoolParam()
  312. {
  313. connection.Query<bool>("select @b", new { b = false }).First()
  314. .IsFalse();
  315. }
  316. // http://code.google.com/p/dapper-dot-net/issues/detail?id=70
  317. // https://connect.microsoft.com/VisualStudio/feedback/details/381934/sqlparameter-dbtype-dbtype-time-sets-the-parameter-to-sqldbtype-datetime-instead-of-sqldbtype-time
  318. public void TestTimeSpanParam()
  319. {
  320. connection.Query<TimeSpan>("select @ts", new { ts = TimeSpan.FromMinutes(42) }).First()
  321. .IsEqualTo(TimeSpan.FromMinutes(42));
  322. }
  323. public void TestStrings()
  324. {
  325. connection.Query<string>(@"select 'a' a union select 'b'")
  326. .IsSequenceEqualTo(new[] { "a", "b" });
  327. }
  328. enum EnumParam : short
  329. {
  330. None, A, B
  331. }
  332. class EnumParamObject
  333. {
  334. public EnumParam A { get; set; }
  335. public EnumParam? B { get; set; }
  336. public EnumParam? C { get; set; }
  337. }
  338. class EnumParamObjectNonNullable
  339. {
  340. public EnumParam A { get; set; }
  341. public EnumParam? B { get; set; }
  342. public EnumParam? C { get; set; }
  343. }
  344. public void TestEnumParamsWithNullable()
  345. {
  346. EnumParam a = EnumParam.A;
  347. EnumParam? b = EnumParam.B, c = null;
  348. var obj = connection.Query<EnumParamObject>("select @a as A, @b as B, @c as C",
  349. new { a, b, c }).Single();
  350. obj.A.IsEqualTo(EnumParam.A);
  351. obj.B.IsEqualTo(EnumParam.B);
  352. obj.C.IsEqualTo(null);
  353. }
  354. public void TestEnumParamsWithoutNullable()
  355. {
  356. EnumParam a = EnumParam.A;
  357. EnumParam b = EnumParam.B, c = 0;
  358. var obj = connection.Query<EnumParamObjectNonNullable>("select @a as A, @b as B, @c as C",
  359. new { a, b, c }).Single();
  360. obj.A.IsEqualTo(EnumParam.A);
  361. obj.B.IsEqualTo(EnumParam.B);
  362. obj.C.IsEqualTo((EnumParam)0);
  363. }
  364. public class Dog
  365. {
  366. public int? Age { get; set; }
  367. public Guid Id { get; set; }
  368. public string Name { get; set; }
  369. public float? Weight { get; set; }
  370. public int IgnoredProperty { get { return 1; } }
  371. }
  372. public void TestExtraFields()
  373. {
  374. var guid = Guid.NewGuid();
  375. var dog = connection.Query<Dog>("select '' as Extra, 1 as Age, 0.1 as Name1 , Id = @id", new { Id = guid });
  376. dog.Count()
  377. .IsEqualTo(1);
  378. dog.First().Age
  379. .IsEqualTo(1);
  380. dog.First().Id
  381. .IsEqualTo(guid);
  382. }
  383. public void TestStrongType()
  384. {
  385. var guid = Guid.NewGuid();
  386. var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });
  387. dog.Count()
  388. .IsEqualTo(1);
  389. dog.First().Age
  390. .IsNull();
  391. dog.First().Id
  392. .IsEqualTo(guid);
  393. }
  394. public void TestSimpleNull()
  395. {
  396. connection.Query<DateTime?>("select null").First().IsNull();
  397. }
  398. public void TestExpando()
  399. {
  400. var rows = connection.Query("select 1 A, 2 B union all select 3, 4").ToList();
  401. ((int)rows[0].A)
  402. .IsEqualTo(1);
  403. ((int)rows[0].B)
  404. .IsEqualTo(2);
  405. ((int)rows[1].A)
  406. .IsEqualTo(3);
  407. ((int)rows[1].B)
  408. .IsEqualTo(4);
  409. }
  410. public void TestStringList()
  411. {
  412. 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" } })
  413. .IsSequenceEqualTo(new[] { "a", "b", "c" });
  414. 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] })
  415. .IsSequenceEqualTo(new string[0]);
  416. }
  417. public void TestExecuteCommand()
  418. {
  419. connection.Execute(@"
  420. set nocount on
  421. create table #t(i int)
  422. set nocount off
  423. insert #t
  424. select @a a union all select @b
  425. set nocount on
  426. drop table #t", new { a = 1, b = 2 }).IsEqualTo(2);
  427. }
  428. public void TestExecuteCommandWithHybridParameters()
  429. {
  430. var p = new DynamicParameters(new { a = 1, b = 2 });
  431. p.Add("c", dbType: DbType.Int32, direction: ParameterDirection.Output);
  432. connection.Execute(@"set @c = @a + @b", p);
  433. p.Get<int>("@c").IsEqualTo(3);
  434. }
  435. public void TestExecuteMultipleCommand()
  436. {
  437. connection.Execute("create table #t(i int)");
  438. int tally = connection.Execute(@"insert #t (i) values(@a)", new[] { new { a = 1 }, new { a = 2 }, new { a = 3 }, new { a = 4 } });
  439. int sum = connection.Query<int>("select sum(i) from #t drop table #t").First();
  440. tally.IsEqualTo(4);
  441. sum.IsEqualTo(10);
  442. }
  443. class Student
  444. {
  445. public string Name { get; set; }
  446. public int Age { get; set; }
  447. }
  448. public void TestExecuteMultipleCommandStrongType()
  449. {
  450. connection.Execute("create table #t(Name nvarchar(max), Age int)");
  451. int tally = connection.Execute(@"insert #t (Name,Age) values(@Name, @Age)", new List<Student>
  452. {
  453. new Student{Age = 1, Name = "sam"},
  454. new Student{Age = 2, Name = "bob"}
  455. });
  456. int sum = connection.Query<int>("select sum(Age) from #t drop table #t").First();
  457. tally.IsEqualTo(2);
  458. sum.IsEqualTo(3);
  459. }
  460. public void TestExecuteMultipleCommandObjectArray()
  461. {
  462. connection.Execute("create table #t(i int)");
  463. int tally = connection.Execute(@"insert #t (i) values(@a)", new object[] { new { a = 1 }, new { a = 2 }, new { a = 3 }, new { a = 4 } });
  464. int sum = connection.Query<int>("select sum(i) from #t drop table #t").First();
  465. tally.IsEqualTo(4);
  466. sum.IsEqualTo(10);
  467. }
  468. public void TestMassiveStrings()
  469. {
  470. var str = new string('X', 20000);
  471. connection.Query<string>("select @a", new { a = str }).First()
  472. .IsEqualTo(str);
  473. }
  474. class TestObj
  475. {
  476. public int _internal;
  477. internal int Internal { set { _internal = value; } }
  478. public int _priv;
  479. private int Priv { set { _priv = value; } }
  480. }
  481. public void TestSetInternal()
  482. {
  483. connection.Query<TestObj>("select 10 as [Internal]").First()._internal.IsEqualTo(10);
  484. }
  485. public void TestSetPrivate()
  486. {
  487. connection.Query<TestObj>("select 10 as [Priv]").First()._priv.IsEqualTo(10);
  488. }
  489. public void TestEnumeration()
  490. {
  491. var en = connection.Query<int>("select 1 as one union all select 2 as one", buffered: false);
  492. var i = en.GetEnumerator();
  493. i.MoveNext();
  494. bool gotException = false;
  495. try
  496. {
  497. var x = connection.Query<int>("select 1 as one", buffered: false).First();
  498. }
  499. catch (Exception)
  500. {
  501. gotException = true;
  502. }
  503. while (i.MoveNext())
  504. { }
  505. // should not exception, since enumertated
  506. en = connection.Query<int>("select 1 as one", buffered: false);
  507. gotException.IsTrue();
  508. }
  509. public void TestEnumerationDynamic()
  510. {
  511. var en = connection.Query("select 1 as one union all select 2 as one", buffered: false);
  512. var i = en.GetEnumerator();
  513. i.MoveNext();
  514. bool gotException = false;
  515. try
  516. {
  517. var x = connection.Query("select 1 as one", buffered: false).First();
  518. }
  519. catch (Exception)
  520. {
  521. gotException = true;
  522. }
  523. while (i.MoveNext())
  524. { }
  525. // should not exception, since enumertated
  526. en = connection.Query("select 1 as one", buffered: false);
  527. gotException.IsTrue();
  528. }
  529. public void TestNakedBigInt()
  530. {
  531. long foo = 12345;
  532. var result = connection.Query<long>("select @foo", new { foo }).Single();
  533. foo.IsEqualTo(result);
  534. }
  535. public void TestBigIntMember()
  536. {
  537. long foo = 12345;
  538. var result = connection.Query<WithBigInt>(@"
  539. declare @bar table(Value bigint)
  540. insert @bar values (@foo)
  541. select * from @bar", new { foo }).Single();
  542. result.Value.IsEqualTo(foo);
  543. }
  544. class WithBigInt
  545. {
  546. public long Value { get; set; }
  547. }
  548. class User
  549. {
  550. public int Id { get; set; }
  551. public string Name { get; set; }
  552. }
  553. class Post
  554. {
  555. public int Id { get; set; }
  556. public User Owner { get; set; }
  557. public string Content { get; set; }
  558. public Comment Comment { get; set; }
  559. }
  560. public void TestMultiMap()
  561. {
  562. var createSql = @"
  563. create table #Users (Id int, Name varchar(20))
  564. create table #Posts (Id int, OwnerId int, Content varchar(20))
  565. insert #Users values(99, 'Sam')
  566. insert #Users values(2, 'I am')
  567. insert #Posts values(1, 99, 'Sams Post1')
  568. insert #Posts values(2, 99, 'Sams Post2')
  569. insert #Posts values(3, null, 'no ones post')
  570. ";
  571. connection.Execute(createSql);
  572. var sql =
  573. @"select * from #Posts p
  574. left join #Users u on u.Id = p.OwnerId
  575. Order by p.Id";
  576. var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post; }).ToList();
  577. var p = data.First();
  578. p.Content.IsEqualTo("Sams Post1");
  579. p.Id.IsEqualTo(1);
  580. p.Owner.Name.IsEqualTo("Sam");
  581. p.Owner.Id.IsEqualTo(99);
  582. data[2].Owner.IsNull();
  583. connection.Execute("drop table #Users drop table #Posts");
  584. }
  585. public void TestMultiMapGridReader()
  586. {
  587. var createSql = @"
  588. create table #Users (Id int, Name varchar(20))
  589. create table #Posts (Id int, OwnerId int, Content varchar(20))
  590. insert #Users values(99, 'Sam')
  591. insert #Users values(2, 'I am')
  592. insert #Posts values(1, 99, 'Sams Post1')
  593. insert #Posts values(2, 99, 'Sams Post2')
  594. insert #Posts values(3, null, 'no ones post')
  595. ";
  596. connection.Execute(createSql);
  597. var sql =
  598. @"select p.*, u.Id, u.Name + '0' Name from #Posts p
  599. left join #Users u on u.Id = p.OwnerId
  600. Order by p.Id
  601. select p.*, u.Id, u.Name + '1' Name from #Posts p
  602. left join #Users u on u.Id = p.OwnerId
  603. Order by p.Id
  604. ";
  605. var grid = connection.QueryMultiple(sql);
  606. for (int i = 0; i < 2; i++)
  607. {
  608. var data = grid.Read<Post, User, Post>((post, user) => { post.Owner = user; return post; }).ToList();
  609. var p = data.First();
  610. p.Content.IsEqualTo("Sams Post1");
  611. p.Id.IsEqualTo(1);
  612. p.Owner.Name.IsEqualTo("Sam" + i);
  613. p.Owner.Id.IsEqualTo(99);
  614. data[2].Owner.IsNull();
  615. }
  616. connection.Execute("drop table #Users drop table #Posts");
  617. }
  618. public void TestQueryMultipleBuffered()
  619. {
  620. using (var grid = connection.QueryMultiple("select 1; select 2; select @x; select 4", new { x = 3 }))
  621. {
  622. var a = grid.Read<int>();
  623. var b = grid.Read<int>();
  624. var c = grid.Read<int>();
  625. var d = grid.Read<int>();
  626. a.Single().Equals(1);
  627. b.Single().Equals(2);
  628. c.Single().Equals(3);
  629. d.Single().Equals(4);
  630. }
  631. }
  632. public void TestQueryMultipleNonBufferedIncorrectOrder()
  633. {
  634. using (var grid = connection.QueryMultiple("select 1; select 2; select @x; select 4", new { x = 3 }))
  635. {
  636. var a = grid.Read<int>(false);
  637. try
  638. {
  639. var b = grid.Read<int>(false);
  640. throw new InvalidOperationException(); // should have thrown
  641. }
  642. catch (InvalidOperationException)
  643. {
  644. // that's expected
  645. }
  646. }
  647. }
  648. public void TestQueryMultipleNonBufferedCcorrectOrder()
  649. {
  650. using (var grid = connection.QueryMultiple("select 1; select 2; select @x; select 4", new { x = 3 }))
  651. {
  652. var a = grid.Read<int>(false).Single();
  653. var b = grid.Read<int>(false).Single();
  654. var c = grid.Read<int>(false).Single();
  655. var d = grid.Read<int>(false).Single();
  656. a.Equals(1);
  657. b.Equals(2);
  658. c.Equals(3);
  659. d.Equals(4);
  660. }
  661. }
  662. public void TestMultiMapDynamic()
  663. {
  664. var createSql = @"
  665. create table #Users (Id int, Name varchar(20))
  666. create table #Posts (Id int, OwnerId int, Content varchar(20))
  667. insert #Users values(99, 'Sam')
  668. insert #Users values(2, 'I am')
  669. insert #Posts values(1, 99, 'Sams Post1')
  670. insert #Posts values(2, 99, 'Sams Post2')
  671. insert #Posts values(3, null, 'no ones post')
  672. ";
  673. connection.Execute(createSql);
  674. var sql =
  675. @"select * from #Posts p
  676. left join #Users u on u.Id = p.OwnerId
  677. Order by p.Id";
  678. var data = connection.Query<dynamic, dynamic, dynamic>(sql, (post, user) => { post.Owner = user; return post; }).ToList();
  679. var p = data.First();
  680. // hairy extension method support for dynamics
  681. ((string)p.Content).IsEqualTo("Sams Post1");
  682. ((int)p.Id).IsEqualTo(1);
  683. ((string)p.Owner.Name).IsEqualTo("Sam");
  684. ((int)p.Owner.Id).IsEqualTo(99);
  685. ((object)data[2].Owner).IsNull();
  686. connection.Execute("drop table #Users drop table #Posts");
  687. }
  688. class Product
  689. {
  690. public int Id { get; set; }
  691. public string Name { get; set; }
  692. public Category Category { get; set; }
  693. }
  694. class Category
  695. {
  696. public int Id { get; set; }
  697. public string Name { get; set; }
  698. public string Description { get; set; }
  699. }
  700. public void TestMultiMapWithSplit() // http://stackoverflow.com/q/6056778/23354
  701. {
  702. var sql = @"select 1 as id, 'abc' as name, 2 as id, 'def' as name";
  703. var product = connection.Query<Product, Category, Product>(sql, (prod, cat) =>
  704. {
  705. prod.Category = cat;
  706. return prod;
  707. }).First();
  708. // assertions
  709. product.Id.IsEqualTo(1);
  710. product.Name.IsEqualTo("abc");
  711. product.Category.Id.IsEqualTo(2);
  712. product.Category.Name.IsEqualTo("def");
  713. }
  714. public void TestMultiMapWithSplitWithNullValue() // http://stackoverflow.com/q/10744728/449906
  715. {
  716. var sql = @"select 1 as id, 'abc' as name, NULL as description, 'def' as name";
  717. var product = connection.Query<Product, Category, Product>(sql, (prod, cat) =>
  718. {
  719. prod.Category = cat;
  720. return prod;
  721. }, splitOn: "description").First();
  722. // assertions
  723. product.Id.IsEqualTo(1);
  724. product.Name.IsEqualTo("abc");
  725. product.Category.IsNull();
  726. }
  727. public void TestMultiMapWithSplitWithNullValueAndSpoofColumn() // http://stackoverflow.com/q/10744728/449906
  728. {
  729. var sql = @"select 1 as id, 'abc' as name, 1 as spoof, NULL as description, 'def' as name";
  730. var product = connection.Query<Product, Category, Product>(sql, (prod, cat) =>
  731. {
  732. prod.Category = cat;
  733. return prod;
  734. }, splitOn: "spoof").First();
  735. // assertions
  736. product.Id.IsEqualTo(1);
  737. product.Name.IsEqualTo("abc");
  738. product.Category.IsNotNull();
  739. product.Category.Id.IsEqualTo(0);
  740. product.Category.Name.IsEqualTo("def");
  741. product.Category.Description.IsNull();
  742. }
  743. public void TestFieldsAndPrivates()
  744. {
  745. var data = connection.Query<TestFieldCaseAndPrivatesEntity>(
  746. @"select a=1,b=2,c=3,d=4,f='5'").Single();
  747. data.a.IsEqualTo(1);
  748. data.GetB().IsEqualTo(2);
  749. data.c.IsEqualTo(3);
  750. data.GetD().IsEqualTo(4);
  751. data.e.IsEqualTo(5);
  752. }
  753. private class TestFieldCaseAndPrivatesEntity
  754. {
  755. public int a { get; set; }
  756. private int b { get; set; }
  757. public int GetB() { return b; }
  758. public int c = 0;
  759. private int d = 0;
  760. public int GetD() { return d; }
  761. public int e { get; set; }
  762. private string f
  763. {
  764. get { return e.ToString(); }
  765. set { e = int.Parse(value); }
  766. }
  767. }
  768. public void TestMultiReaderBasic()
  769. {
  770. 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";
  771. int i, j;
  772. string s;
  773. using (var multi = connection.QueryMultiple(sql))
  774. {
  775. i = multi.Read<int>().First();
  776. s = multi.Read<string>().Single();
  777. j = multi.Read<int>().Sum();
  778. }
  779. Assert.IsEqualTo(i, 1);
  780. Assert.IsEqualTo(s, "abc");
  781. Assert.IsEqualTo(j, 3);
  782. }
  783. public void TestMultiMappingVariations()
  784. {
  785. 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";
  786. var order = connection.Query<dynamic, dynamic, dynamic, dynamic>(sql, (o, owner, creator) => { o.Owner = owner; o.Creator = creator; return o; }).First();
  787. Assert.IsEqualTo(order.Id, 1);
  788. Assert.IsEqualTo(order.Content, "a");
  789. Assert.IsEqualTo(order.Owner.Id, 2);
  790. Assert.IsEqualTo(order.Owner.Content, "b");
  791. Assert.IsEqualTo(order.Creator.Id, 3);
  792. Assert.IsEqualTo(order.Creator.Content, "c");
  793. order = connection.Query<dynamic, dynamic, dynamic, dynamic, dynamic>(sql, (o, owner, creator, address) =>
  794. {
  795. o.Owner = owner;
  796. o.Creator = creator;
  797. o.Owner.Address = address;
  798. return o;
  799. }).First();
  800. Assert.IsEqualTo(order.Id, 1);
  801. Assert.IsEqualTo(order.Content, "a");
  802. Assert.IsEqualTo(order.Owner.Id, 2);
  803. Assert.IsEqualTo(order.Owner.Content, "b");
  804. Assert.IsEqualTo(order.Creator.Id, 3);
  805. Assert.IsEqualTo(order.Creator.Content, "c");
  806. Assert.IsEqualTo(order.Owner.Address.Id, 4);
  807. Assert.IsEqualTo(order.Owner.Address.Content, "d");
  808. 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();
  809. Assert.IsEqualTo(order.Id, 1);
  810. Assert.IsEqualTo(order.Content, "a");
  811. Assert.IsEqualTo(order.B.Id, 2);
  812. Assert.IsEqualTo(order.B.Content, "b");
  813. Assert.IsEqualTo(order.C.Id, 3);
  814. Assert.IsEqualTo(order.C.Content, "c");
  815. Assert.IsEqualTo(order.C.D.Id, 4);
  816. Assert.IsEqualTo(order.C.D.Content, "d");
  817. Assert.IsEqualTo(order.E.Id, 5);
  818. Assert.IsEqualTo(order.E.Content, "e");
  819. }
  820. class InheritanceTest1
  821. {
  822. public string Base1 { get; set; }
  823. public string Base2 { get; private set; }
  824. }
  825. class InheritanceTest2 : InheritanceTest1
  826. {
  827. public string Derived1 { get; set; }
  828. public string Derived2 { get; private set; }
  829. }
  830. public void TestInheritance()
  831. {
  832. // Test that inheritance works.
  833. var list = connection.Query<InheritanceTest2>("select 'One' as Derived1, 'Two' as Derived2, 'Three' as Base1, 'Four' as Base2");
  834. list.First().Derived1.IsEqualTo("One");
  835. list.First().Derived2.IsEqualTo("Two");
  836. list.First().Base1.IsEqualTo("Three");
  837. list.First().Base2.IsEqualTo("Four");
  838. }
  839. public class PostCE
  840. {
  841. public int ID { get; set; }
  842. public string Title { get; set; }
  843. public string Body { get; set; }
  844. public AuthorCE Author { get; set; }
  845. }
  846. public class AuthorCE
  847. {
  848. public int ID { get; set; }
  849. public string Name { get; set; }
  850. }
  851. public void MultiRSSqlCE()
  852. {
  853. if (File.Exists("Test.sdf"))
  854. File.Delete("Test.sdf");
  855. var cnnStr = "Data Source = Test.sdf;";
  856. var engine = new SqlCeEngine(cnnStr);
  857. engine.CreateDatabase();
  858. using (var cnn = new SqlCeConnection(cnnStr))
  859. {
  860. cnn.Open();
  861. cnn.Execute("create table Posts (ID int, Title nvarchar(50), Body nvarchar(50), AuthorID int)");
  862. cnn.Execute("create table Authors (ID int, Name nvarchar(50))");
  863. cnn.Execute("insert Posts values (1,'title','body',1)");
  864. cnn.Execute("insert Posts values(2,'title2','body2',null)");
  865. cnn.Execute("insert Authors values(1,'sam')");
  866. 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();
  867. var firstPost = data.First();
  868. firstPost.Title.IsEqualTo("title");
  869. firstPost.Author.Name.IsEqualTo("sam");
  870. data[1].Author.IsNull();
  871. cnn.Close();
  872. }
  873. }
  874. enum TestEnum : byte
  875. {
  876. Bla = 1
  877. }
  878. class TestEnumClass
  879. {
  880. public TestEnum? EnumEnum { get; set; }
  881. }
  882. class TestEnumClassNoNull
  883. {
  884. public TestEnum EnumEnum { get; set; }
  885. }
  886. public void TestEnumWeirdness()
  887. {
  888. connection.Query<TestEnumClass>("select null as [EnumEnum]").First().EnumEnum.IsEqualTo(null);
  889. connection.Query<TestEnumClass>("select cast(1 as tinyint) as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
  890. }
  891. public void TestEnumStrings()
  892. {
  893. connection.Query<TestEnumClassNoNull>("select 'BLA' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
  894. connection.Query<TestEnumClassNoNull>("select 'bla' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
  895. connection.Query<TestEnumClass>("select 'BLA' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
  896. connection.Query<TestEnumClass>("select 'bla' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
  897. }
  898. public void TestSupportForDynamicParameters()
  899. {
  900. var p = new DynamicParameters();
  901. p.Add("name", "bob");
  902. p.Add("age", dbType: DbType.Int32, direction: ParameterDirection.Output);
  903. connection.Query<string>("set @age = 11 select @name", p).First().IsEqualTo("bob");
  904. p.Get<int>("age").IsEqualTo(11);
  905. }
  906. public void TestSupportForExpandoObjectParameters()
  907. {
  908. dynamic p = new ExpandoObject();
  909. p.name = "bob";
  910. object parameters = p;
  911. string result = connection.Query<string>("select @name", parameters).First();
  912. result.IsEqualTo("bob");
  913. }
  914. public void TestProcSupport()
  915. {
  916. var p = new DynamicParameters();
  917. p.Add("a", 11);
  918. p.Add("b", dbType: DbType.Int32, direction: ParameterDirection.Output);
  919. p.Add("c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
  920. connection.Execute(@"create proc #TestProc
  921. @a int,
  922. @b int output
  923. as
  924. begin
  925. set @b = 999
  926. select 1111
  927. return @a
  928. end");
  929. connection.Query<int>("#TestProc", p, commandType: CommandType.StoredProcedure).First().IsEqualTo(1111);
  930. p.Get<int>("c").IsEqualTo(11);
  931. p.Get<int>("b").IsEqualTo(999);
  932. }
  933. public void TestDbString()
  934. {
  935. 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",
  936. new
  937. {
  938. a = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true },
  939. b = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = false },
  940. c = new DbString { Value = "abcde", IsFixedLength = false, Length = 10, IsAnsi = true },
  941. d = new DbString { Value = "abcde", IsFixedLength = false, Length = 10, IsAnsi = false },
  942. e = new DbString { Value = "abcde", IsAnsi = true },
  943. f = new DbString { Value = "abcde", IsAnsi = false },
  944. }).First();
  945. ((int)obj.a).IsEqualTo(10);
  946. ((int)obj.b).IsEqualTo(20);
  947. ((int)obj.c).IsEqualTo(5);
  948. ((int)obj.d).IsEqualTo(10);
  949. ((int)obj.e).IsEqualTo(5);
  950. ((int)obj.f).IsEqualTo(10);
  951. }
  952. class Person
  953. {
  954. public int PersonId { get; set; }
  955. public string Name { get; set; }
  956. }
  957. class Address
  958. {
  959. public int AddressId { get; set; }
  960. public string Name { get; set; }
  961. public int PersonId { get; set; }
  962. }
  963. class Extra
  964. {
  965. public int Id { get; set; }
  966. public string Name { get; set; }
  967. }
  968. public void TestFlexibleMultiMapping()
  969. {
  970. var sql =
  971. @"select
  972. 1 as PersonId, 'bob' as Name,
  973. 2 as AddressId, 'abc street' as Name, 1 as PersonId,
  974. 3 as Id, 'fred' as Name
  975. ";
  976. var personWithAddress = connection.Query<Person, Address, Extra, Tuple<Person, Address, Extra>>
  977. (sql, (p, a, e) => Tuple.Create(p, a, e), splitOn: "AddressId,Id").First();
  978. personWithAddress.Item1.PersonId.IsEqualTo(1);
  979. personWithAddress.Item1.Name.IsEqualTo("bob");
  980. personWithAddress.Item2.AddressId.IsEqualTo(2);
  981. personWithAddress.Item2.Name.IsEqualTo("abc street");
  982. personWithAddress.Item2.PersonId.IsEqualTo(1);
  983. personWithAddress.Item3.Id.IsEqualTo(3);
  984. personWithAddress.Item3.Name.IsEqualTo("fred");
  985. }
  986. public void TestMultiMappingWithSplitOnSpaceBetweenCommas()
  987. {
  988. var sql = @"select
  989. 1 as PersonId, 'bob' as Name,
  990. 2 as AddressId, 'abc street' as Name, 1 as PersonId,
  991. 3 as Id, 'fred' as Name
  992. ";
  993. var personWithAddress = connection.Query<Person, Address, Extra, Tuple<Person, Address, Extra>>
  994. (sql, (p, a, e) => Tuple.Create(p, a, e), splitOn: "AddressId, Id").First();
  995. personWithAddress.Item1.PersonId.IsEqualTo(1);
  996. personWithAddress.Item1.Name.IsEqualTo("bob");
  997. personWithAddress.Item2.AddressId.IsEqualTo(2);
  998. personWithAddress.Item2.Name.IsEqualTo("abc street");
  999. personWithAddress.Item2.PersonId.IsEqualTo(1);
  1000. personWithAddress.Item3.Id.IsEqualTo(3);
  1001. personWithAddress.Item3.Name.IsEqualTo("fred");
  1002. }
  1003. public void TestFastExpandoSupportsIDictionary()
  1004. {
  1005. var row = connection.Query("select 1 A, 'two' B").First() as IDictionary<string, object>;
  1006. row["A"].IsEqualTo(1);
  1007. row["B"].IsEqualTo("two");
  1008. }
  1009. class PrivateDan
  1010. {
  1011. public int Shadow { get; set; }
  1012. private string ShadowInDB
  1013. {
  1014. set
  1015. {
  1016. Shadow = value == "one" ? 1 : 0;
  1017. }
  1018. }
  1019. }
  1020. public void TestDapperSetsPrivates()
  1021. {
  1022. connection.Query<PrivateDan>("select 'one' ShadowInDB").First().Shadow.IsEqualTo(1);
  1023. }
  1024. class IntDynamicParam : Dapper.SqlMapper.IDynamicParameters
  1025. {
  1026. IEnumerable<int> numbers;
  1027. public IntDynamicParam(IEnumerable<int> numbers)
  1028. {
  1029. this.numbers = numbers;
  1030. }
  1031. public void AddParameters(IDbCommand command, Dapper.SqlMapper.Identity identity)
  1032. {
  1033. var sqlCommand = (SqlCommand)command;
  1034. sqlCommand.CommandType = CommandType.StoredProcedure;
  1035. List<Microsoft.SqlServer.Server.SqlDataRecord> number_list = new List<Microsoft.SqlServer.Server.SqlDataRecord>();
  1036. // Create an SqlMetaData object that describes our table type.
  1037. Microsoft.SqlServer.Server.SqlMetaData[] tvp_definition = { new Microsoft.SqlServer.Server.SqlMetaData("n", SqlDbType.Int) };
  1038. foreach (int n in numbers)
  1039. {
  1040. // Create a new record, using the metadata array above.
  1041. Microsoft.SqlServer.Server.SqlDataRecord rec = new Microsoft.SqlServer.Server.SqlDataRecord(tvp_definition);
  1042. rec.SetInt32(0, n); // Set the value.
  1043. number_list.Add(rec); // Add it to the list.
  1044. }
  1045. // Add the table parameter.
  1046. var p = sqlCommand.Parameters.Add("ints", SqlDbType.Structured);
  1047. p.Direction = ParameterDirection.Input;
  1048. p.TypeName = "int_list_type";
  1049. p.Value = number_list;
  1050. }
  1051. }
  1052. // SQL Server specific test to demonstrate TVP
  1053. public void TestTVP()
  1054. {
  1055. try
  1056. {
  1057. connection.Execute("CREATE TYPE int_list_type AS TABLE (n int NOT NULL PRIMARY KEY)");
  1058. connection.Execute("CREATE PROC get_ints @ints int_list_type READONLY AS select * from @ints");
  1059. var nums = connection.Query<int>("get_ints", new IntDynamicParam(new int[] { 1, 2, 3 })).ToList();
  1060. nums[0].IsEqualTo(1);
  1061. nums[1].IsEqualTo(2);
  1062. nums[2].IsEqualTo(3);
  1063. nums.Count.IsEqualTo(3);
  1064. }
  1065. finally
  1066. {
  1067. try
  1068. {
  1069. connection.Execute("DROP PROC get_ints");
  1070. }
  1071. finally
  1072. {
  1073. connection.Execute("DROP TYPE int_list_type");
  1074. }
  1075. }
  1076. }
  1077. class DynamicParameterWithIntTVP : Dapper.DynamicParameters, Dapper.SqlMapper.IDynamicParameters
  1078. {
  1079. IEnumerable<int> numbers;
  1080. public DynamicParameterWithIntTVP(IEnumerable<int> numbers)
  1081. {
  1082. this.numbers = numbers;
  1083. }
  1084. public new void AddParameters(IDbCommand command, Dapper.SqlMapper.Identity identity)
  1085. {
  1086. base.AddParameters(command, identity);
  1087. var sqlCommand = (SqlCommand)command;
  1088. sqlCommand.CommandType = CommandType.StoredProcedure;
  1089. List<Microsoft.SqlServer.Server.SqlDataRecord> number_list = new List<Microsoft.SqlServer.Server.SqlDataRecord>();
  1090. // Create an SqlMetaData object that describes our table type.
  1091. Microsoft.SqlServer.Server.SqlMetaData[] tvp_definition = { new Microsoft.SqlServer.Server.SqlMetaData("n", SqlDbType.Int) };
  1092. foreach (int n in numbers)
  1093. {
  1094. // Create a new record, using the metadata array above.
  1095. Microsoft.SqlServer.Server.SqlDataRecord rec = new Microsoft.SqlServer.Server.SqlDataRecord(tvp_definition);
  1096. rec.SetInt32(0, n); // Set the value.
  1097. number_list.Add(rec); // Add it to the list.
  1098. }
  1099. // Add the table parameter.
  1100. var p = sqlCommand.Parameters.Add("ints", SqlDbType.Structured);
  1101. p.Direction = ParameterDirection.Input;
  1102. p.TypeName = "int_list_type";
  1103. p.Value = number_list;
  1104. }
  1105. }
  1106. public void TestTVPWithAdditionalParams()
  1107. {
  1108. try
  1109. {
  1110. connection.Execute("CREATE TYPE int_list_type AS TABLE (n int NOT NULL PRIMARY KEY)");
  1111. connection.Execute("CREATE PROC get_values @ints int_list_type READONLY, @stringParam varchar(20), @dateParam datetime AS select i.*, @stringParam as stringParam, @dateParam as dateParam from @ints i");
  1112. var dynamicParameters = new DynamicParameterWithIntTVP(new int[] { 1, 2, 3 });
  1113. dynamicParameters.AddDynamicParams(new { stringParam = "stringParam", dateParam = new DateTime(2012, 1, 1) });
  1114. var results = connection.Query("get_values", dynamicParameters, commandType: CommandType.StoredProcedure).ToList();
  1115. results.Count.IsEqualTo(3);
  1116. for (int i = 0; i < results.Count; i++)
  1117. {
  1118. var result = results[i];
  1119. Assert.IsEqualTo(i + 1, result.n);
  1120. Assert.IsEqualTo("stringParam", result.stringParam);
  1121. Assert.IsEqualTo(new DateTime(2012, 1, 1), result.dateParam);
  1122. }
  1123. }
  1124. finally
  1125. {
  1126. try
  1127. {
  1128. connection.Execute("DROP PROC get_values");
  1129. }
  1130. finally
  1131. {
  1132. connection.Execute("DROP TYPE int_list_type");
  1133. }
  1134. }
  1135. }
  1136. class Parent
  1137. {
  1138. public int Id { get; set; }
  1139. public readonly List<Child> Children = new List<Child>();
  1140. }
  1141. class Child
  1142. {
  1143. public int Id { get; set; }
  1144. }
  1145. public void ParentChildIdentityAssociations()
  1146. {
  1147. var lookup = new Dictionary<int, Parent>();
  1148. 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",
  1149. (parent, child) =>
  1150. {
  1151. Parent found;
  1152. if (!lookup.TryGetValue(parent.Id, out found))
  1153. {
  1154. lookup.Add(parent.Id, found = parent);
  1155. }
  1156. found.Children.Add(child);
  1157. return found;
  1158. }).Distinct().ToDictionary(p => p.Id);
  1159. p

Large files files are truncated, but you can click here to view the full file