/src/NHibernate.Test/Async/Criteria/SelectModeTest/SelectModeTest.cs

http://github.com/nhibernate/nhibernate-core · C# · 840 lines · 724 code · 95 blank · 21 comment · 23 complexity · 24264784396ea805d06139368d7292d7 MD5 · raw file

  1. //------------------------------------------------------------------------------
  2. // <auto-generated>
  3. // This code was generated by AsyncGenerator.
  4. //
  5. // Changes to this file may cause incorrect behavior and will be lost if
  6. // the code is regenerated.
  7. // </auto-generated>
  8. //------------------------------------------------------------------------------
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Data;
  12. using System.Linq;
  13. using System.Linq.Expressions;
  14. using NHibernate.Cfg.MappingSchema;
  15. using NHibernate.Criterion;
  16. using NHibernate.Linq;
  17. using NHibernate.Mapping.ByCode;
  18. using NHibernate.SqlCommand;
  19. using NHibernate.Transform;
  20. using NUnit.Framework;
  21. namespace NHibernate.Test.Criteria.SelectModeTest
  22. {
  23. using System.Threading.Tasks;
  24. /// <summary>
  25. /// Tests for select mode
  26. /// </summary>
  27. [TestFixture]
  28. public class SelectModeTestAsync : TestCaseMappingByCode
  29. {
  30. private Guid _parentEntityComplexId;
  31. [Test]
  32. public async Task SelectModeJoinOnlyAsync()
  33. {
  34. using (var sqlLog = new SqlLogSpy())
  35. using (var session = OpenSession())
  36. {
  37. EntityComplex root = null;
  38. root = await (session.QueryOver(() => root)
  39. //Child1 is required solely for filtering, no need to be fetched, so skip it from select statement
  40. .JoinQueryOver(r => r.Child1, JoinType.InnerJoin)
  41. .Fetch(SelectMode.JoinOnly, child1 => child1)
  42. .Take(1)
  43. .SingleOrDefaultAsync());
  44. Assert.That(root, Is.Not.Null);
  45. Assert.That(NHibernateUtil.IsInitialized(root), Is.True);
  46. Assert.That(root.Child1, Is.Not.Null);
  47. Assert.That(NHibernateUtil.IsInitialized(root.Child1), Is.False, "Joined ManyToOne Child1 should not be fetched.");
  48. Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected");
  49. }
  50. }
  51. [Test]
  52. public async Task SelectModeDetachedQueryOverAsync()
  53. {
  54. using (var sqlLog = new SqlLogSpy())
  55. using (var session = OpenSession())
  56. {
  57. EntityComplex root = null;
  58. root = await (QueryOver.Of(() => root)
  59. .Where(x => x.Id == _parentEntityComplexId)
  60. .Fetch(SelectMode.Fetch, r => r.Child1)
  61. .GetExecutableQueryOver(session)
  62. .SingleOrDefaultAsync());
  63. Assert.That(root, Is.Not.Null);
  64. Assert.That(NHibernateUtil.IsInitialized(root), Is.True);
  65. Assert.That(root.Child1, Is.Not.Null);
  66. Assert.That(NHibernateUtil.IsInitialized(root.Child1), Is.True, "Joined ManyToOne Child1 should not be fetched.");
  67. Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected");
  68. }
  69. }
  70. [Test]
  71. public async Task SelectModeFetchAsync()
  72. {
  73. using (var sqlLog = new SqlLogSpy())
  74. using (var session = OpenSession())
  75. {
  76. var list = await (session.QueryOver<EntityComplex>()
  77. .Fetch(SelectMode.Fetch, ec => ec.Child1)
  78. .JoinQueryOver(ec => ec.ChildrenList, JoinType.InnerJoin)
  79. //now we can fetch inner joined collection
  80. .Fetch(SelectMode.Fetch, childrenList => childrenList)
  81. .TransformUsing(Transformers.DistinctRootEntity)
  82. .ListAsync());
  83. var root = list.FirstOrDefault();
  84. Assert.That(root, Is.Not.Null);
  85. Assert.That(NHibernateUtil.IsInitialized(root), Is.True);
  86. Assert.That(root.Child1, Is.Not.Null);
  87. Assert.That(NHibernateUtil.IsInitialized(root.Child1), Is.True, "Entity must be initialized");
  88. Assert.That(NHibernateUtil.IsInitialized(root.ChildrenList), Is.True, "ChildrenList Inner Joined collection must be initialized");
  89. Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected");
  90. }
  91. }
  92. //Check that SelecMode survives query cloning
  93. [Test]
  94. public async Task SelectModeFetch_ClonedQueryOverAsync()
  95. {
  96. using (var sqlLog = new SqlLogSpy())
  97. using (var session = OpenSession())
  98. {
  99. var list = await (session.QueryOver<EntityComplex>()
  100. .Fetch(SelectMode.Fetch, ec => ec.Child1)
  101. .JoinQueryOver(ec => ec.ChildrenList, JoinType.InnerJoin)
  102. //now we can fetch inner joined collection
  103. .Fetch(SelectMode.Fetch, childrenList => childrenList)
  104. .TransformUsing(Transformers.DistinctRootEntity)
  105. .Clone()
  106. .ListAsync());
  107. var root = list.FirstOrDefault();
  108. Assert.That(root, Is.Not.Null);
  109. Assert.That(NHibernateUtil.IsInitialized(root), Is.True);
  110. Assert.That(root.Child1, Is.Not.Null);
  111. Assert.That(NHibernateUtil.IsInitialized(root.Child1), Is.True, "Entity must be initialized");
  112. Assert.That(NHibernateUtil.IsInitialized(root.ChildrenList), Is.True, "ChildrenList Inner Joined collection must be initialized");
  113. Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected");
  114. }
  115. }
  116. [Test]
  117. public async Task SelectModeUndefinedAsync()
  118. {
  119. using (var sqlLog = new SqlLogSpy())
  120. using (var session = OpenSession())
  121. {
  122. //SelectMode.Default is no op - fetching is controlled by default behavior:
  123. //SameTypeChild won't be loaded, and ChildrenList collection won't be fetched due to InnerJoin
  124. var list = await (session.QueryOver<EntityComplex>()
  125. .Fetch(SelectMode.Undefined, ec => ec.SameTypeChild)
  126. .JoinQueryOver(ec => ec.ChildrenList, JoinType.InnerJoin)
  127. .Fetch(SelectMode.Undefined, childrenList => childrenList)
  128. .TransformUsing(Transformers.DistinctRootEntity)
  129. .ListAsync());
  130. //So it's a full equivalent of the following query (without SelectMode)
  131. session.QueryOver<EntityComplex>()
  132. .JoinQueryOver(ec => ec.ChildrenList, JoinType.InnerJoin)
  133. .TransformUsing(Transformers.DistinctRootEntity);
  134. var root = list.FirstOrDefault();
  135. Assert.That(root, Is.Not.Null);
  136. Assert.That(NHibernateUtil.IsInitialized(root), Is.True);
  137. Assert.That(root.SameTypeChild, Is.Not.Null);
  138. Assert.That(NHibernateUtil.IsInitialized(root.SameTypeChild), Is.False, "Entity must be NOT initialized");
  139. Assert.That(NHibernateUtil.IsInitialized(root.ChildrenList), Is.False, "ChildrenList Inner Joined collection must be NOT initialized");
  140. Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected");
  141. }
  142. }
  143. [Test]
  144. public async Task SelectModeFetchLazyPropertiesAsync()
  145. {
  146. using (var sqlLog = new SqlLogSpy())
  147. using (var session = OpenSession())
  148. {
  149. var root = await (session.QueryOver<EntityComplex>()
  150. .Fetch(SelectMode.FetchLazyProperties, ec => ec)
  151. .Where(ec => ec.LazyProp != null)
  152. .Take(1)
  153. .SingleOrDefaultAsync());
  154. Assert.That(root, Is.Not.Null);
  155. Assert.That(NHibernateUtil.IsInitialized(root), Is.True);
  156. Assert.That(root.LazyProp, Is.Not.Null);
  157. Assert.That(NHibernateUtil.IsPropertyInitialized(root, nameof(root.LazyProp)), Is.True, "Lazy property must be fetched.");
  158. Assert.That(NHibernateUtil.IsPropertyInitialized(root, nameof(root.LazyProp2)), Is.True, "Lazy property must be fetched.");
  159. Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected");
  160. }
  161. }
  162. [Test]
  163. public async Task SelectModeFetchKeepLazyPropertiesUninitializedAsync()
  164. {
  165. using (var sqlLog = new SqlLogSpy())
  166. using (var session = OpenSession())
  167. {
  168. var root = await (session.QueryOver<EntityComplex>()
  169. .Fetch(SelectMode.Fetch, ec => ec)
  170. .Where(ec => ec.LazyProp != null)
  171. .Take(1)
  172. .SingleOrDefaultAsync());
  173. Assert.That(root, Is.Not.Null);
  174. Assert.That(NHibernateUtil.IsInitialized(root), Is.True);
  175. Assert.That(NHibernateUtil.IsPropertyInitialized(root, nameof(root.LazyProp)), Is.False, "Property must be lazy.");
  176. Assert.That(NHibernateUtil.IsPropertyInitialized(root, nameof(root.LazyProp2)), Is.False, "Property must be lazy.");
  177. Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected");
  178. }
  179. }
  180. [Test]
  181. public async Task SelectModeFetchLazyPropertiesFetchGroupAsync()
  182. {
  183. using (var sqlLog = new SqlLogSpy())
  184. using (var session = OpenSession())
  185. {
  186. var root = await (session.QueryOver<EntityComplex>()
  187. .Fetch(SelectMode.FetchLazyPropertyGroup, ec => ec.LazyProp, ec => ec.LazyProp2, ec => ec.SameTypeChild.LazyProp2)
  188. .Where(ec => ec.Id == _parentEntityComplexId)
  189. .SingleOrDefaultAsync());
  190. Assert.That(root, Is.Not.Null);
  191. Assert.That(NHibernateUtil.IsInitialized(root), Is.True);
  192. Assert.That(root.LazyProp, Is.Not.Null);
  193. Assert.That(NHibernateUtil.IsPropertyInitialized(root, nameof(root.LazyProp)), Is.True, "Lazy property must be fetched.");
  194. Assert.That(NHibernateUtil.IsPropertyInitialized(root, nameof(root.LazyProp2)), Is.True, "Lazy property must be fetched.");
  195. Assert.That(NHibernateUtil.IsInitialized(root.SameTypeChild), Is.True, "Object must be initialized.");
  196. Assert.That(root.SameTypeChild, Is.Not.Null);
  197. Assert.That(NHibernateUtil.IsPropertyInitialized(root.SameTypeChild, nameof(root.LazyProp2)), Is.True, "Lazy property must be fetched.");
  198. Assert.That(NHibernateUtil.IsPropertyInitialized(root.SameTypeChild, nameof(root.LazyProp)), Is.False, "Property must be lazy.");
  199. Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected");
  200. }
  201. }
  202. [Test]
  203. public async Task SelectModeChildFetchForMultipleCollections_SingleDbRoundtripAsync()
  204. {
  205. SkipFutureTestIfNotSupported();
  206. using (var sqlLog = new SqlLogSpy())
  207. using (var session = OpenSession())
  208. {
  209. EntityComplex root = null;
  210. var futureRoot = session
  211. .QueryOver(() => root)
  212. .Where(r => r.Id == _parentEntityComplexId)
  213. .FutureValue();
  214. session
  215. .QueryOver(() => root)
  216. //Only ID is added to SELECT statement for root so it's index scan only
  217. .Fetch(SelectMode.ChildFetch, ec => ec)
  218. .Fetch(SelectMode.Fetch, ec => ec.ChildrenList)
  219. .Where(r => r.Id == _parentEntityComplexId)
  220. .Future();
  221. session
  222. .QueryOver(() => root)
  223. .Fetch(SelectMode.ChildFetch, ec => ec)
  224. .Fetch(SelectMode.Fetch, ec => ec.ChildrenListEmpty)
  225. .Where(r => r.Id == _parentEntityComplexId)
  226. .Future();
  227. root = await (futureRoot.GetValueAsync());
  228. Assert.That(root?.ChildrenList, Is.Not.Null);
  229. Assert.That(root?.ChildrenListEmpty, Is.Not.Null);
  230. Assert.That(NHibernateUtil.IsInitialized(root?.ChildrenList), "ChildrenList must be initialized");
  231. Assert.That(NHibernateUtil.IsInitialized(root?.ChildrenListEmpty), "ChildrenListEmpty must be initialized");
  232. Assert.That(root?.ChildrenList, Is.Not.Empty, "ChildrenList must not be empty");
  233. Assert.That(root?.ChildrenListEmpty, Is.Empty, "ChildrenListEmpty must be empty");
  234. Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected");
  235. }
  236. }
  237. [Test]
  238. public async Task SelectModeChildFetchForMultipleCollectionsAsync()
  239. {
  240. using (var session = OpenSession())
  241. {
  242. EntityComplex root = null;
  243. root = await (session
  244. .QueryOver(() => root)
  245. .Where(r => r.Id == _parentEntityComplexId)
  246. .SingleOrDefaultAsync());
  247. await (session
  248. .QueryOver(() => root)
  249. //Only ID is added to SELECT statement for root so it's index scan only
  250. .Fetch(SelectMode.ChildFetch, ec => ec)
  251. .Fetch(SelectMode.Fetch, ec => ec.ChildrenList)
  252. .Where(r => r.Id == _parentEntityComplexId)
  253. .ListAsync());
  254. await (session
  255. .QueryOver(() => root)
  256. .Fetch(SelectMode.ChildFetch, ec => ec)
  257. .Fetch(SelectMode.Fetch, ec => ec.ChildrenListEmpty)
  258. .Where(r => r.Id == _parentEntityComplexId)
  259. .ListAsync());
  260. Assert.That(root?.ChildrenList, Is.Not.Null);
  261. Assert.That(root?.ChildrenListEmpty, Is.Not.Null);
  262. Assert.That(NHibernateUtil.IsInitialized(root?.ChildrenList), "ChildrenList must be initialized");
  263. Assert.That(NHibernateUtil.IsInitialized(root?.ChildrenListEmpty), "ChildrenListEmpty must be initialized");
  264. Assert.That(root?.ChildrenList, Is.Not.Empty, "ChildrenList must not be empty");
  265. Assert.That(root?.ChildrenListEmpty, Is.Empty, "ChildrenListEmpty must be empty");
  266. }
  267. }
  268. [Test]
  269. public async Task SelectModeJoinOnlyEntityJoinAsync()
  270. {
  271. using (var sqlLog = new SqlLogSpy())
  272. using (var session = OpenSession())
  273. {
  274. EntityComplex parentJoin = null;
  275. EntitySimpleChild rootChild = null;
  276. rootChild = await (session.QueryOver(() => rootChild)
  277. .JoinEntityQueryOver(() => parentJoin, Restrictions.Where(() => rootChild.ParentId == parentJoin.Id))
  278. .Fetch(SelectMode.JoinOnly, a => a)
  279. .Take(1)
  280. .SingleOrDefaultAsync());
  281. parentJoin = await (session.LoadAsync<EntityComplex>(rootChild.ParentId));
  282. Assert.That(rootChild, Is.Not.Null);
  283. Assert.That(NHibernateUtil.IsInitialized(rootChild), Is.True);
  284. Assert.That(rootChild.ParentId, Is.Not.Null);
  285. Assert.That(NHibernateUtil.IsInitialized(parentJoin), Is.False, "Entity Join must not be initialized.");
  286. Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected");
  287. }
  288. }
  289. [Test]
  290. public async Task SelectModeFetchLazyPropertiesForEntityJoinAsync()
  291. {
  292. using (var sqlLog = new SqlLogSpy())
  293. using (var session = OpenSession())
  294. {
  295. EntityComplex parentJoin = null;
  296. EntitySimpleChild rootChild = null;
  297. rootChild = await (session.QueryOver(() => rootChild)
  298. .JoinEntityQueryOver(() => parentJoin, Restrictions.Where(() => rootChild.ParentId == parentJoin.Id))
  299. .Fetch(SelectMode.FetchLazyProperties, ec => ec)
  300. .Take(1)
  301. .SingleOrDefaultAsync());
  302. parentJoin = await (session.LoadAsync<EntityComplex>(rootChild.ParentId));
  303. Assert.That(rootChild, Is.Not.Null);
  304. Assert.That(NHibernateUtil.IsInitialized(rootChild), Is.True);
  305. Assert.That(NHibernateUtil.IsInitialized(parentJoin), Is.True);
  306. Assert.That(NHibernateUtil.IsPropertyInitialized(parentJoin, nameof(parentJoin.LazyProp)), Is.Not.Null.Or.Empty);
  307. Assert.That(parentJoin.LazyProp, Is.Not.Null.Or.Empty);
  308. Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1), "Only one SQL select is expected");
  309. }
  310. }
  311. [Test]
  312. public async Task SelectModeChildFetchLoadsNotLoadedObjectAsync()
  313. {
  314. using (var sqlLog = new SqlLogSpy())
  315. using (var session = OpenSession())
  316. {
  317. EntityComplex root = null;
  318. root = await (session.QueryOver(() => root)
  319. .Fetch(SelectMode.ChildFetch, r => r)
  320. .JoinQueryOver(ec => ec.ChildrenList)
  321. .Fetch(SelectMode.Fetch, simpleChild => simpleChild)
  322. .Take(1)
  323. .SingleOrDefaultAsync());
  324. Assert.That(root, Is.Not.Null, "root is not loaded");
  325. Assert.That(NHibernateUtil.IsInitialized(root), Is.False, "root should not be initialized");
  326. Assert.That(sqlLog.Appender.GetEvents(), Has.Length.EqualTo(1), "Only one SQL select is expected");
  327. // The root was not initialized but its children collection is immediately initialized... A bit weird feature.
  328. Assert.That(NHibernateUtil.IsInitialized(root.ChildrenList), Is.True, "root children should be initialized");
  329. Assert.That(root.ChildrenList, Has.Count.EqualTo(1).And.None.Null, "Unexpected children collection content");
  330. }
  331. }
  332. [Test]
  333. public async Task SelectModeChildFetchLoadsNotLoaded_NotProxifiedObjectAsync()
  334. {
  335. using (var sqlLog = new SqlLogSpy())
  336. using (var session = OpenSession())
  337. {
  338. EntityEager root = null;
  339. root = await (session.QueryOver(() => root)
  340. .Fetch(SelectMode.ChildFetch, r => r)
  341. .JoinQueryOver(ec => ec.ChildrenList)
  342. .Fetch(SelectMode.Fetch, simpleChild => simpleChild)
  343. .Take(1)
  344. .SingleOrDefaultAsync());
  345. Assert.That(root, Is.Not.Null, "root is loaded");
  346. Assert.That(NHibernateUtil.IsInitialized(root), Is.True, "root should be initialized");
  347. Assert.That(sqlLog.Appender.GetEvents(), Has.Length.EqualTo(2), "Two SQL selects are expected (query + loading not proxified entity)");
  348. Assert.That(NHibernateUtil.IsInitialized(root.ChildrenList), Is.True, "root children should be initialized");
  349. Assert.That(root.ChildrenList, Has.Count.EqualTo(1).And.None.Null, "Unexpected children collection content");
  350. }
  351. }
  352. [Test]
  353. public async Task SelectModeChildFetchDeep_AliasedAsync()
  354. {
  355. using (var session = OpenSession())
  356. {
  357. EntityComplex root = null;
  358. var list = await (session
  359. .QueryOver(() => root)
  360. .ListAsync());
  361. await (session
  362. .QueryOver(() => root)
  363. .Fetch(SelectMode.ChildFetch, () => root)
  364. .Fetch(SelectMode.Fetch, () => root.ChildrenList)
  365. .ListAsync());
  366. await (session
  367. .QueryOver(() => root)
  368. .Fetch(SelectMode.ChildFetch, () => root, () => root.ChildrenList)
  369. .Fetch(SelectMode.Fetch, () => root.ChildrenList[0].Children)
  370. .ListAsync());
  371. await (session
  372. .QueryOver(() => root)
  373. .Fetch(SelectMode.JoinOnly, () => root.ChildrenList)
  374. .Fetch(SelectMode.ChildFetch,() => root, () => root.ChildrenList[0].Children)
  375. .Fetch(SelectMode.Fetch, () => root.ChildrenList[0].Children[0].Children)
  376. .ListAsync());
  377. root = list.First(r => r.Id == _parentEntityComplexId);
  378. Assert.That(root?.ChildrenList, Is.Not.Null);
  379. Assert.That(NHibernateUtil.IsInitialized(root?.ChildrenList));
  380. Assert.That(NHibernateUtil.IsInitialized(root?.ChildrenList[0].Children));
  381. Assert.That(NHibernateUtil.IsInitialized(root?.ChildrenList[0].Children[0].Children));
  382. }
  383. }
  384. [Test]
  385. public void JoinOnlyRootEntityIsNotSupportedAsync()
  386. {
  387. using (var session = OpenSession())
  388. {
  389. var query = session.QueryOver<EntityComplex>()
  390. .Fetch(SelectMode.JoinOnly, ec => ec)
  391. .Fetch(SelectMode.Fetch, ec => ec.Child1)
  392. .Take(1);
  393. Assert.ThrowsAsync<NotSupportedException>(() => query.SingleOrDefaultAsync());
  394. }
  395. }
  396. [Test]
  397. public void SkipRootEntityIsNotSupportedAsync()
  398. {
  399. using (var session = OpenSession())
  400. {
  401. var query = session.QueryOver<EntityComplex>()
  402. .Fetch(SelectMode.Skip, ec => ec)
  403. .Fetch(SelectMode.Fetch, ec => ec.Child1)
  404. .Take(1);
  405. Assert.ThrowsAsync<NotSupportedException>(() => query.SingleOrDefaultAsync());
  406. }
  407. }
  408. [Test]
  409. public async Task OrderedInnerJoinFetchAsync()
  410. {
  411. using (var session = OpenSession())
  412. {
  413. var list = await (session.QueryOver<EntityComplex>()
  414. .Where(ec => ec.Id == _parentEntityComplexId)
  415. .JoinQueryOver(c => c.ChildrenList).Fetch(SelectMode.Fetch, child => child)
  416. .TransformUsing(Transformers.DistinctRootEntity)
  417. .ListAsync());
  418. var childList = list[0].ChildrenList;
  419. Assert.That(list[0].ChildrenList.Count, Is.GreaterThan(1));
  420. Assert.That(list[0].ChildrenList, Is.EqualTo(list[0].ChildrenList.OrderByDescending(c => c.OrderIdx)), "wrong order");
  421. }
  422. }
  423. [Test, Obsolete]
  424. public async Task FetchModeEagerForLazyAsync()
  425. {
  426. using (var session = OpenSession())
  427. {
  428. var parent = (await (session.QueryOver<EntityComplex>()
  429. .Fetch(ec => ec.Child1).Eager
  430. .Fetch(ec => ec.ChildrenList).Eager
  431. .Where(ec => ec.Child1 != null)
  432. .TransformUsing(Transformers.DistinctRootEntity)
  433. .ListAsync()))
  434. .FirstOrDefault();
  435. Assert.That(parent?.Child1, Is.Not.Null);
  436. Assert.That(NHibernateUtil.IsInitialized(parent?.Child1), Is.True);
  437. Assert.That(NHibernateUtil.IsInitialized(parent?.ChildrenList), Is.True);
  438. }
  439. }
  440. [Test, Obsolete]
  441. public async Task FetchModeLazyForLazyAsync()
  442. {
  443. using (var session = OpenSession())
  444. {
  445. var parent = (await (session.QueryOver<EntityComplex>()
  446. .Fetch(ec => ec.Child1).Lazy
  447. .Fetch(ec => ec.ChildrenList).Lazy
  448. .Where(ec => ec.Child1 != null)
  449. .TransformUsing(Transformers.DistinctRootEntity)
  450. .ListAsync()))
  451. .FirstOrDefault();
  452. Assert.That(parent?.Child1, Is.Not.Null);
  453. Assert.That(NHibernateUtil.IsInitialized(parent?.Child1), Is.False);
  454. Assert.That(NHibernateUtil.IsInitialized(parent?.ChildrenList), Is.False);
  455. }
  456. }
  457. [Test, Obsolete]
  458. public async Task FetchModeDefaultForLazyAsync()
  459. {
  460. using (var session = OpenSession())
  461. {
  462. var parent = (await (session.QueryOver<EntityComplex>()
  463. .Fetch(ec => ec.Child1).Default
  464. .Fetch(ec => ec.ChildrenList).Default
  465. .Where(ec => ec.Child1 != null)
  466. .TransformUsing(Transformers.DistinctRootEntity)
  467. .ListAsync()))
  468. .FirstOrDefault();
  469. Assert.That(parent?.Child1, Is.Not.Null);
  470. Assert.That(NHibernateUtil.IsInitialized(parent?.Child1), Is.False);
  471. Assert.That(NHibernateUtil.IsInitialized(parent?.ChildrenList), Is.False);
  472. }
  473. }
  474. [Test, Obsolete]
  475. public async Task FetchModeLazyForEagerAsync()
  476. {
  477. using (var session = OpenSession())
  478. {
  479. var parent = (await (session.QueryOver<EntityEager>().ListAsync())).FirstOrDefault();
  480. Assert.That(parent?.ChildrenList, Is.Not.Null, "Failed test set up. Object must not be null.");
  481. Assert.That(parent?.ChildrenList, Is.Not.Null, "Failed test set up. ChildrenList must be eager loaded with parent.");
  482. }
  483. using (var session = OpenSession())
  484. {
  485. var parent = (await (session.QueryOver<EntityEager>()
  486. .Fetch(ec => ec.ChildrenList).Lazy
  487. .TransformUsing(Transformers.DistinctRootEntity)
  488. .ListAsync()))
  489. .FirstOrDefault();
  490. Assert.That(parent?.ChildrenList, Is.Not.Null, "collection should not be null");
  491. Assert.That(NHibernateUtil.IsInitialized(parent?.ChildrenList), Is.False, "Eager collection should not be initialized.");
  492. }
  493. }
  494. [Test, Obsolete]
  495. public async Task FetchModeDefaultForEagerAsync()
  496. {
  497. using (var session = OpenSession())
  498. {
  499. var parent = (await (session.QueryOver<EntityEager>()
  500. .Fetch(ec => ec.ChildrenList).Default
  501. .TransformUsing(Transformers.DistinctRootEntity)
  502. .ListAsync()))
  503. .FirstOrDefault();
  504. Assert.That(parent?.ChildrenList, Is.Not.Null, "collection should not be null");
  505. Assert.That(NHibernateUtil.IsInitialized(parent?.ChildrenList), Is.True, "eager collection should be initialized");
  506. }
  507. }
  508. [Test, Obsolete]
  509. public async Task FetchModeEagerForEagerAsync()
  510. {
  511. using (var session = OpenSession())
  512. {
  513. var parent = (await (session.QueryOver<EntityEager>()
  514. .Fetch(ec => ec.ChildrenList).Eager
  515. .TransformUsing(Transformers.DistinctRootEntity)
  516. .ListAsync()))
  517. .FirstOrDefault();
  518. Assert.That(parent?.ChildrenList, Is.Not.Null, "collection should not be null");
  519. Assert.That(NHibernateUtil.IsInitialized(parent?.ChildrenList), Is.True, "eager collection should be initialized");
  520. }
  521. }
  522. private void SkipFutureTestIfNotSupported()
  523. {
  524. if (Sfi.ConnectionProvider.Driver.SupportsMultipleQueries == false)
  525. Assert.Ignore("Driver {0} does not support multi-queries", Sfi.ConnectionProvider.Driver.GetType().FullName);
  526. }
  527. #region Test Setup
  528. protected override HbmMapping GetMappings()
  529. {
  530. var mapper = new ModelMapper();
  531. mapper.Class<EntityEager>(
  532. rc =>
  533. {
  534. rc.Lazy(false);
  535. rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
  536. rc.Version(ep => ep.Version, vm => { });
  537. rc.Property(x => x.Name);
  538. MapList(rc, p => p.ChildrenList, CollectionFetchMode.Join);
  539. });
  540. MapSimpleChild<EntityEagerChild>(
  541. mapper,
  542. rc => { rc.Lazy(false); });
  543. mapper.Class<EntityComplex>(
  544. rc =>
  545. {
  546. rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
  547. rc.Version(ep => ep.Version, vm => { });
  548. rc.Property(x => x.Name);
  549. rc.Property(ep => ep.LazyProp, m =>
  550. {
  551. m.Lazy(true);
  552. m.FetchGroup("LazyGroup");
  553. });
  554. rc.Property(ep => ep.LazyProp2, m =>
  555. {
  556. m.Lazy(true);
  557. m.FetchGroup("LazyGroup2");
  558. });
  559. rc.ManyToOne(
  560. ep => ep.Child1,
  561. m =>
  562. {
  563. m.Column("Child1Id");
  564. m.ForeignKey("none");
  565. });
  566. rc.ManyToOne(
  567. ep => ep.Child2,
  568. m =>
  569. {
  570. m.Column("Child2Id");
  571. m.ForeignKey("none");
  572. });
  573. rc.ManyToOne(ep => ep.SameTypeChild, m =>
  574. {
  575. m.Column("SameTypeChildId");
  576. m.ForeignKey("none");
  577. });
  578. MapList(rc, ep => ep.ChildrenList, mapper: m => m.OrderBy("OrderIdx desc"));
  579. MapList(rc, ep => ep.ChildrenListEmpty);
  580. });
  581. MapSimpleChild(
  582. mapper,
  583. default(EntitySimpleChild),
  584. c => c.Children,
  585. rc =>
  586. {
  587. rc.Property(sc => sc.LazyProp, mp => mp.Lazy(true));
  588. rc.Property(sc => sc.OrderIdx);
  589. });
  590. MapSimpleChild(mapper, default(Level2Child), c => c.Children);
  591. MapSimpleChild<Level3Child>(mapper);
  592. return mapper.CompileMappingForAllExplicitlyAddedEntities();
  593. }
  594. private static void MapSimpleChild<TChild>(ModelMapper mapper, Action<IClassMapper<TChild>> action = null) where TChild : BaseChild
  595. {
  596. MapSimpleChild<TChild, object>(mapper, default(TChild), null, action);
  597. }
  598. private static void MapSimpleChild<TChild, TSubChild>(ModelMapper mapper, TChild obj, Expression<Func<TChild, IEnumerable<TSubChild>>> expression, Action<IClassMapper<TChild>> action = null) where TChild : BaseChild
  599. {
  600. mapper.Class<TChild>(
  601. rc =>
  602. {
  603. rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
  604. rc.Property(x => x.Name);
  605. rc.Property(c => c.ParentId);
  606. if (expression != null)
  607. {
  608. MapList(rc, expression);
  609. }
  610. action?.Invoke(rc);
  611. });
  612. }
  613. private static void MapList<TParent, TElement>(IClassMapper<TParent> rc, Expression<Func<TParent, IEnumerable<TElement>>> expression, CollectionFetchMode fetchMode = null, Action<IBagPropertiesMapper<TParent, TElement>> mapper = null) where TParent : class
  614. {
  615. rc.Bag(
  616. expression,
  617. m =>
  618. {
  619. m.Key(
  620. km =>
  621. {
  622. km.Column(
  623. ckm =>
  624. {
  625. ckm.Name("ParentId");
  626. });
  627. km.ForeignKey("none");
  628. });
  629. m.Cascade(Mapping.ByCode.Cascade.All);
  630. if (fetchMode != null)
  631. {
  632. m.Fetch(fetchMode);
  633. }
  634. mapper?.Invoke(m);
  635. },
  636. a => a.OneToMany());
  637. }
  638. protected override void OnTearDown()
  639. {
  640. using (ISession session = OpenSession())
  641. using (ITransaction transaction = session.BeginTransaction(IsolationLevel.Serializable))
  642. {
  643. session.Query<Level3Child>().Delete();
  644. session.Query<Level2Child>().Delete();
  645. session.Query<EntityComplex>().Delete();
  646. session.Query<EntitySimpleChild>().Delete();
  647. session.Query<EntityEagerChild>().Delete();
  648. session.Query<EntityEager>().Delete();
  649. session.Flush();
  650. transaction.Commit();
  651. }
  652. }
  653. protected override void OnSetUp()
  654. {
  655. using (var session = OpenSession())
  656. using (var transaction = session.BeginTransaction())
  657. {
  658. var child1 = new EntitySimpleChild
  659. {
  660. Name = "Child1",
  661. LazyProp = "LazyFromSimpleChild1",
  662. Children = new List<Level2Child>
  663. {
  664. new Level2Child()
  665. {
  666. Name = "Level2.1",
  667. Children = new List<Level3Child>
  668. {
  669. new Level3Child
  670. {
  671. Name = "Level3.1.1",
  672. },
  673. new Level3Child
  674. {
  675. Name = "Level3.1.2"
  676. },
  677. }
  678. },
  679. new Level2Child
  680. {
  681. Name = "Level2.2",
  682. Children = new List<Level3Child>
  683. {
  684. new Level3Child
  685. {
  686. Name = "Level3.2.1"
  687. },
  688. new Level3Child
  689. {
  690. Name = "Level3.2.2"
  691. },
  692. }
  693. }
  694. },
  695. OrderIdx = 100
  696. };
  697. var child2 = new EntitySimpleChild
  698. {
  699. Name = "Child2",
  700. LazyProp = "LazyFromSimpleChild2",
  701. };
  702. var child3 = new EntitySimpleChild
  703. {
  704. Name = "Child3",
  705. OrderIdx = 0
  706. };
  707. var child4 = new EntitySimpleChild
  708. {
  709. Name = "Child4",
  710. OrderIdx = 50
  711. };
  712. var parent = new EntityComplex
  713. {
  714. Name = "ComplexEntityParent",
  715. Child1 = child1,
  716. Child2 = child2,
  717. LazyProp = "SomeBigValue",
  718. LazyProp2 = "SomeBigValue2",
  719. SameTypeChild = new EntityComplex()
  720. {
  721. Name = "ComplexEntityChild",
  722. LazyProp = "LazyProp1",
  723. LazyProp2 = "LazyProp2",
  724. },
  725. ChildrenList = new List<EntitySimpleChild> {child3, child1, child4 },
  726. ChildrenListEmpty = new List<EntityComplex> { },
  727. };
  728. session.Save(new EntityEager()
  729. {
  730. Name = "Eager",
  731. ChildrenList = new List<EntityEagerChild>
  732. { new EntityEagerChild(){Name ="EagerChild"}}
  733. });
  734. session.Save(child1);
  735. session.Save(child2);
  736. session.Save(parent.SameTypeChild);
  737. session.Save(parent);
  738. session.Flush();
  739. transaction.Commit();
  740. _parentEntityComplexId = parent.Id;
  741. }
  742. }
  743. #endregion Test Setup
  744. }
  745. }