diff --git a/src/NHibernate.Test/Async/FetchLazyProperties/FetchLazyPropertiesFixture.cs b/src/NHibernate.Test/Async/FetchLazyProperties/FetchLazyPropertiesFixture.cs
new file mode 100644
index 00000000000..d6a85b966c0
--- /dev/null
+++ b/src/NHibernate.Test/Async/FetchLazyProperties/FetchLazyPropertiesFixture.cs
@@ -0,0 +1,1008 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by AsyncGenerator.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+
+using System;
+using System.Linq;
+using NHibernate.Cache;
+using NHibernate.Cfg;
+using NHibernate.Hql.Ast.ANTLR;
+using NHibernate.Linq;
+using NUnit.Framework;
+using Environment = NHibernate.Cfg.Environment;
+
+namespace NHibernate.Test.FetchLazyProperties
+{
+ using System.Threading.Tasks;
+ using System.Threading;
+ [TestFixture]
+ public class FetchLazyPropertiesFixtureAsync : TestCase
+ {
+ protected override string MappingsAssembly
+ {
+ get { return "NHibernate.Test"; }
+ }
+
+ protected override string[] Mappings
+ {
+ get { return new[] { "FetchLazyProperties.Mappings.hbm.xml" }; }
+ }
+
+ protected override bool AppliesTo(Dialect.Dialect dialect)
+ {
+ return dialect.SupportsTemporaryTables;
+ }
+
+ protected override void Configure(Configuration configuration)
+ {
+ base.Configure(configuration);
+ configuration.Properties[Environment.CacheProvider] = typeof(HashtableCacheProvider).AssemblyQualifiedName;
+ configuration.Properties[Environment.UseSecondLevelCache] = "true";
+ }
+
+ protected override void OnSetUp()
+ {
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ var currAnimalId = 1;
+ Person lastPerson = null;
+ for (var i = 2; i > 0; i--)
+ {
+ var person = lastPerson = GeneratePerson(i, lastPerson);
+ person.Pets.Add(GenerateCat(currAnimalId++, person));
+ person.Pets.Add(GenerateDog(currAnimalId++, person));
+ s.Save(person);
+ }
+
+ tx.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ s.CreateQuery("delete from Animal").ExecuteUpdate();
+ s.CreateQuery("update Person set BestFriend = null").ExecuteUpdate();
+ s.CreateQuery("delete from Person").ExecuteUpdate();
+ s.CreateQuery("delete from Continent").ExecuteUpdate();
+ tx.Commit();
+ }
+ }
+
+ #region FetchComponent
+
+ [Test]
+ public async Task TestHqlFetchComponentAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.CreateQuery("from Person fetch Address where Id = 1").UniqueResultAsync());
+ }
+
+ AssertFetchComponent(person);
+ }
+
+ [Test]
+ public async Task TestLinqFetchComponentAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.Query().Fetch(o => o.Address).FirstOrDefaultAsync(o => o.Id == 1));
+ }
+
+ AssertFetchComponent(person);
+ }
+
+ private static void AssertFetchComponent(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ Assert.That(person.Address.City, Is.EqualTo("City1"));
+ Assert.That(person.Address.Country, Is.EqualTo("Country1"));
+ }
+
+ #endregion
+
+ #region FetchFormula
+
+ [Test]
+ public async Task TestHqlFetchFormulaAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.CreateQuery("from Person fetch Formula where Id = 1").UniqueResultAsync());
+ }
+
+ AssertFetchFormula(person);
+ }
+
+ [Test]
+ public async Task TestLinqFetchFormulaAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.Query().Fetch(o => o.Formula).FirstOrDefaultAsync(o => o.Id == 1));
+ }
+
+ AssertFetchFormula(person);
+ }
+
+ private static void AssertFetchFormula(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+
+ Assert.That(person.Formula, Is.EqualTo(1));
+ }
+
+ #endregion
+
+ #region FetchProperty
+
+ [Test]
+ public async Task TestHqlFetchPropertyAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.CreateQuery("from Person fetch Image where Id = 1").UniqueResultAsync());
+ }
+
+ AssertFetchProperty(person);
+ }
+
+ [Test]
+ public async Task TestLinqFetchPropertyAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.Query().Fetch(o => o.Image).FirstOrDefaultAsync(o => o.Id == 1));
+ }
+
+ AssertFetchProperty(person);
+ }
+
+ private static void AssertFetchProperty(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ Assert.That(person.Image, Has.Length.EqualTo(1));
+ }
+
+ #endregion
+
+
+ #region FetchComponentAndFormulaTwoQueryReadOnly
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public async Task TestHqlFetchComponentAndFormulaTwoQueryReadOnlyAsync(bool readOnly, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ Person person;
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = await (s.CreateQuery("from Person fetch Address where Id = 1").SetReadOnly(readOnly).UniqueResultAsync(cancellationToken));
+ person = await (s.CreateQuery("from Person fetch Formula where Id = 1").SetReadOnly(readOnly).UniqueResultAsync(cancellationToken));
+
+ await (tx.CommitAsync(cancellationToken));
+ }
+
+ AssertFetchComponentAndFormulaTwoQuery(person);
+ }
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public async Task TestLinqFetchComponentAndFormulaTwoQueryAsync(bool readOnly, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ Person person;
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = await (s.Query().Fetch(o => o.Address).WithOptions(o => o.SetReadOnly(readOnly)).FirstOrDefaultAsync(o => o.Id == 1, cancellationToken));
+ person = await (s.Query().Fetch(o => o.Formula).WithOptions(o => o.SetReadOnly(readOnly)).FirstOrDefaultAsync(o => o.Id == 1, cancellationToken));
+
+ await (tx.CommitAsync(cancellationToken));
+ }
+
+ AssertFetchComponentAndFormulaTwoQuery(person);
+ }
+
+ private static void AssertFetchComponentAndFormulaTwoQuery(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+
+ Assert.That(person.Address.City, Is.EqualTo("City1"));
+ Assert.That(person.Address.Country, Is.EqualTo("Country1"));
+ Assert.That(person.Formula, Is.EqualTo(1));
+ }
+
+ #endregion
+
+ #region FetchAllProperties
+
+ [Test]
+ public async Task TestHqlFetchAllPropertiesAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.CreateQuery("from Person fetch all properties where Id = 1").UniqueResultAsync());
+ }
+
+ AssertFetchAllProperties(person);
+ }
+
+ [Test]
+ public async Task TestLinqFetchAllPropertiesAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.Query().FetchLazyProperties().FirstOrDefaultAsync(o => o.Id == 1));
+ }
+
+ AssertFetchAllProperties(person);
+ }
+
+ private static void AssertFetchAllProperties(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+
+ Assert.That(person.Image, Has.Length.EqualTo(1));
+ Assert.That(person.Address.City, Is.EqualTo("City1"));
+ Assert.That(person.Address.Country, Is.EqualTo("Country1"));
+ Assert.That(person.Formula, Is.EqualTo(1));
+ }
+
+ #endregion
+
+ #region FetchAllPropertiesIndividually
+
+ [Test]
+ public async Task TestHqlFetchAllPropertiesIndividuallyAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.CreateQuery("from Person fetch Image fetch Address fetch Formula fetch Image where Id = 1").UniqueResultAsync());
+ }
+
+ AssertFetchAllProperties(person);
+ }
+
+ [Test]
+ public async Task TestLinqFetchAllPropertiesIndividuallyAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.Query().Fetch(o => o.Image).Fetch(o => o.Address).Fetch(o => o.Formula).FirstOrDefaultAsync(o => o.Id == 1));
+ }
+
+ AssertFetchAllProperties(person);
+ }
+
+ #endregion
+
+ #region FetchFormulaAndManyToOneComponent
+
+ [Test]
+ public async Task TestHqlFetchFormulaAndManyToOneComponentAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.CreateQuery("from Person p fetch p.Formula left join fetch p.BestFriend bf fetch bf.Address where p.Id = 1")
+ .UniqueResultAsync());
+ }
+
+ AssertFetchFormulaAndManyToOneComponent(person);
+ }
+
+ [Test]
+ public async Task TestLinqFetchFormulaAndManyToOneComponentAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.Query()
+ .Fetch(o => o.Formula)
+ .Fetch(o => o.BestFriend).ThenFetch(o => o.Address)
+ .FirstOrDefaultAsync(o => o.Id == 1));
+
+ }
+
+ AssertFetchFormulaAndManyToOneComponent(person);
+ }
+
+ private static void AssertFetchFormulaAndManyToOneComponent(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+
+ Assert.That(NHibernateUtil.IsInitialized(person.BestFriend), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Formula"), Is.False);
+
+ Assert.That(person.Formula, Is.EqualTo(1));
+ Assert.That(person.BestFriend.Address.City, Is.EqualTo("City2"));
+ Assert.That(person.BestFriend.Address.Country, Is.EqualTo("Country2"));
+ }
+
+ #endregion
+
+ #region FetchFormulaAndManyToOneComponentList
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public async Task TestHqlFetchFormulaAndManyToOneComponentListAsync(bool descending, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = (await (s.CreateQuery("from Person p fetch p.Formula left join fetch p.BestFriend bf fetch bf.Address order by p.Id" + (descending ? " desc" : ""))
+ .ListAsync(cancellationToken))).FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchFormulaAndManyToOneComponentList(person);
+ }
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public async Task TestLinqFetchFormulaAndManyToOneComponentListAsync(bool descending, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ IQueryable query = s.Query()
+ .Fetch(o => o.Formula)
+ .Fetch(o => o.BestFriend).ThenFetch(o => o.Address);
+ query = descending ? query.OrderByDescending(o => o.Id) : query.OrderBy(o => o.Id);
+ person = (await (query
+ .ToListAsync(cancellationToken)))
+ .FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchFormulaAndManyToOneComponentList(person);
+ }
+
+ private static void AssertFetchFormulaAndManyToOneComponentList(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+
+ Assert.That(NHibernateUtil.IsInitialized(person.BestFriend), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Formula"), Is.True);
+
+ Assert.That(person.Formula, Is.EqualTo(1));
+ Assert.That(person.BestFriend.Address.City, Is.EqualTo("City2"));
+ Assert.That(person.BestFriend.Address.Country, Is.EqualTo("Country2"));
+ }
+
+ #endregion
+
+ #region FetchManyToOneAllProperties
+
+ [Test]
+ public async Task TestHqlFetchManyToOneAllPropertiesAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = (await (s.CreateQuery("from Person p left join fetch p.BestFriend fetch all properties")
+ .ListAsync())).FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchManyToOneAllProperties(person);
+ }
+
+ [Test]
+ public async Task TestLinqFetchManyToOneAllPropertiesAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = (await (s.Query()
+ .Fetch(o => o.BestFriend).FetchLazyProperties()
+ .ToListAsync()))
+ .FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchManyToOneAllProperties(person);
+ }
+
+ private static void AssertFetchManyToOneAllProperties(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ Assert.That(NHibernateUtil.IsInitialized(person.BestFriend), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Image"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Formula"), Is.True);
+
+ Assert.That(person.BestFriend.Formula, Is.EqualTo(2));
+ Assert.That(person.BestFriend.Address.City, Is.EqualTo("City2"));
+ Assert.That(person.BestFriend.Address.Country, Is.EqualTo("Country2"));
+ Assert.That(person.BestFriend.Image, Has.Length.EqualTo(2));
+ }
+
+ #endregion
+
+ #region FetchFormulaAndOneToManyComponent
+
+ [Test]
+ public async Task TestHqlFetchFormulaAndOneToManyComponentAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = (await (s.CreateQuery("from Person p fetch p.Formula left join fetch p.Dogs dog fetch dog.Address where p.Id = 1")
+ .ListAsync()))
+ .FirstOrDefault();
+ }
+
+ AssertFetchFormulaAndOneToManyComponent(person);
+ }
+
+ [Test]
+ public async Task TestLinqFetchFormulaAndOneToManyComponentAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = (await (s.Query()
+ .Fetch(o => o.Formula)
+ .FetchMany(o => o.Dogs).ThenFetch(o => o.Address)
+ .Where(o => o.Id == 1)
+ .ToListAsync()))
+ .FirstOrDefault();
+ }
+
+ AssertFetchFormulaAndOneToManyComponent(person);
+ }
+
+ private static void AssertFetchFormulaAndOneToManyComponent(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+
+ Assert.That(NHibernateUtil.IsInitialized(person.Dogs), Is.True);
+ Assert.That(NHibernateUtil.IsInitialized(person.BestFriend), Is.False);
+ Assert.That(NHibernateUtil.IsInitialized(person.Pets), Is.False);
+
+ Assert.That(person.Formula, Is.EqualTo(1));
+ Assert.That(person.Dogs, Has.Count.EqualTo(1));
+ foreach (var dog in person.Dogs)
+ {
+ Assert.That(NHibernateUtil.IsPropertyInitialized(dog, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(dog, "Formula"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(dog, "Address"), Is.True);
+
+ Assert.That(dog.Address.City, Is.EqualTo("City1"));
+ Assert.That(dog.Address.Country, Is.EqualTo("Country1"));
+ }
+ }
+
+ #endregion
+
+ #region FetchOneToManyProperty
+
+ [Test]
+ public async Task TestHqlFetchOneToManyPropertyAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = (await (s.CreateQuery("from Person p left join fetch p.Cats cat fetch cat.SecondImage where p.Id = 1")
+ .ListAsync()))
+ .FirstOrDefault();
+ }
+
+ AssertFetchOneToManyProperty(person);
+ }
+
+ [Test]
+ public async Task TestLinqFetchOneToManyPropertyAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = (await (s.Query()
+ .FetchMany(o => o.Cats).ThenFetch(o => o.SecondImage)
+ .Where(o => o.Id == 1)
+ .ToListAsync()))
+ .FirstOrDefault();
+ }
+
+ AssertFetchOneToManyProperty(person);
+ }
+
+ private static void AssertFetchOneToManyProperty(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ Assert.That(NHibernateUtil.IsInitialized(person.BestFriend), Is.False);
+ Assert.That(NHibernateUtil.IsInitialized(person.Pets), Is.False);
+ Assert.That(NHibernateUtil.IsInitialized(person.Cats), Is.True);
+
+ Assert.That(person.Cats, Has.Count.EqualTo(1));
+ foreach (var cat in person.Cats)
+ {
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Formula"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondImage"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondFormula"), Is.False);
+
+ Assert.That(cat.SecondImage, Has.Length.EqualTo(6));
+ }
+ }
+
+ #endregion
+
+ #region FetchNotMappedProperty
+
+ [Test]
+ public void TestHqlFetchNotMappedPropertyAsync()
+ {
+ using (var s = OpenSession())
+ {
+ Assert.ThrowsAsync(
+ async () =>
+ {
+ var person = await (s.CreateQuery("from Person p fetch p.BirthYear where p.Id = 1").UniqueResultAsync());
+ });
+ }
+ }
+
+ [Test]
+ public void TestLinqFetchNotMappedPropertyAsync()
+ {
+ using (var s = OpenSession())
+ {
+ Assert.ThrowsAsync(
+ async () =>
+ {
+ var person = await (s.Query().Fetch(o => o.BirthYear).FirstOrDefaultAsync(o => o.Id == 1));
+ });
+ }
+ }
+
+ #endregion
+
+ #region FetchComponentManyToOne
+
+ [Test]
+ public async Task TestHqlFetchComponentManyToOneAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.CreateQuery("from Person p fetch p.Address left join fetch p.Address.Continent where p.Id = 1").UniqueResultAsync());
+ }
+
+ AssertFetchComponentManyToOne(person);
+ }
+
+ [Test]
+ public async Task TestLinqFetchComponentManyToOneAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.Query().Fetch(o => o.Address).ThenFetch(o => o.Continent).FirstOrDefaultAsync(o => o.Id == 1));
+ }
+
+ AssertFetchComponentManyToOne(person);
+ }
+
+ private static void AssertFetchComponentManyToOne(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ Assert.That(NHibernateUtil.IsInitialized(person.Address.Continent), Is.True);
+
+ Assert.That(person.Address.City, Is.EqualTo("City1"));
+ Assert.That(person.Address.Country, Is.EqualTo("Country1"));
+ Assert.That(person.Address.Continent.Name, Is.EqualTo("Continent1"));
+ }
+
+ #endregion
+
+ #region FetchSubClassFormula
+
+ [Test]
+ public async Task TestHqlFetchSubClassFormulaAsync()
+ {
+ Animal animal;
+ using (var s = OpenSession())
+ {
+ animal = await (s.CreateQuery("from Animal a fetch a.SecondFormula where a.Id = 1").UniqueResultAsync());
+ }
+
+ AssertFetchSubClassFormula(animal);
+ }
+
+ [Test]
+ public async Task TestLinqFetchSubClassFormulaAsync()
+ {
+ Animal animal;
+ using (var s = OpenSession())
+ {
+ animal = await (s.Query().Fetch(o => ((Cat) o).SecondFormula).FirstAsync(o => o.Id == 1));
+ }
+
+ AssertFetchSubClassFormula(animal);
+ }
+
+ private static void AssertFetchSubClassFormula(Animal animal)
+ {
+ Assert.That(animal, Is.AssignableTo(typeof(Cat)));
+ var cat = (Cat) animal;
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondFormula"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondImage"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Formula"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Image"), Is.False);
+ }
+
+ #endregion
+
+ #region FetchSubClassProperty
+
+ [Test]
+ public async Task TestHqlFetchSubClassPropertyAsync()
+ {
+ Animal animal;
+ using (var s = OpenSession())
+ {
+ animal = await (s.CreateQuery("from Animal a fetch a.SecondImage where a.Id = 1").UniqueResultAsync());
+ }
+
+ AssertFetchSubClassProperty(animal);
+ }
+
+ [Test]
+ public async Task TestLinqFetchSubClassPropertyAsync()
+ {
+ Animal animal;
+ using (var s = OpenSession())
+ {
+ animal = await (s.Query().Fetch(o => ((Cat) o).SecondImage).FirstAsync(o => o.Id == 1));
+ }
+
+ AssertFetchSubClassProperty(animal);
+ }
+
+ private static void AssertFetchSubClassProperty(Animal animal)
+ {
+ Assert.That(animal, Is.AssignableTo(typeof(Cat)));
+ var cat = (Cat) animal;
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondFormula"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondImage"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Formula"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Image"), Is.False);
+ }
+
+ #endregion
+
+ #region FetchSubClassAllProperty
+
+ [Test]
+ public async Task TestHqlFetchSubClassAllPropertiesAsync()
+ {
+ Animal animal;
+ using (var s = OpenSession())
+ {
+ animal = await (s.CreateQuery("from Animal a fetch all properties where a.Id = 1").UniqueResultAsync());
+ }
+
+ AssertFetchSubClassAllProperties(animal);
+ }
+
+ [Test]
+ public async Task TestLinqFetchSubClassAllPropertiesAsync()
+ {
+ Animal animal;
+ using (var s = OpenSession())
+ {
+ animal = await (s.Query().FetchLazyProperties().FirstAsync(o => o.Id == 1));
+ }
+
+ AssertFetchSubClassAllProperties(animal);
+ }
+
+ private static void AssertFetchSubClassAllProperties(Animal animal)
+ {
+ Assert.That(animal, Is.AssignableTo(typeof(Cat)));
+ var cat = (Cat) animal;
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondFormula"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondImage"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Formula"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Image"), Is.True);
+ }
+
+ #endregion
+
+ #region FetchAllPropertiesWithFetchProperty
+
+ [Test]
+ public void TestHqlFetchAllPropertiesWithFetchPropertyAsync()
+ {
+ using (var s = OpenSession())
+ {
+ Assert.ThrowsAsync(
+ async () =>
+ {
+ var person = await (s.CreateQuery("from Person p fetch p.Address fetch all properties where p.Id = 1").UniqueResultAsync());
+ });
+ Assert.ThrowsAsync(
+ async () =>
+ {
+ var person = await (s.CreateQuery("from Person p fetch all properties fetch p.Address where p.Id = 1").UniqueResultAsync());
+ });
+ }
+ }
+
+ [Test]
+ public void TestLinqFetchAllPropertiesWithFetchPropertyAsync()
+ {
+ using (var s = OpenSession())
+ {
+ Assert.ThrowsAsync(
+ async () =>
+ {
+ var person = await (s.Query().Fetch(o => o.Address).FetchLazyProperties().FirstOrDefaultAsync(o => o.Id == 1));
+ });
+ Assert.ThrowsAsync(
+ async () =>
+ {
+ var person = await (s.Query().FetchLazyProperties().Fetch(o => o.Address).FirstOrDefaultAsync(o => o.Id == 1));
+ });
+ }
+ }
+
+ #endregion
+
+ [Test]
+ public async Task TestHqlFetchComponentAliasAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = await (s.CreateQuery("from Person p fetch p.Address where p.Id = 1").UniqueResultAsync());
+ }
+
+ AssertFetchComponent(person);
+ }
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public async Task TestFetchComponentAndFormulaTwoQueryCacheAsync(bool readOnly, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ await (TestLinqFetchComponentAndFormulaTwoQueryAsync(readOnly, cancellationToken));
+
+ Person person;
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = await (s.GetAsync(1, cancellationToken));
+
+ await (tx.CommitAsync(cancellationToken));
+ }
+
+ AssertFetchComponentAndFormulaTwoQuery(person);
+ }
+
+ [Test]
+ public async Task TestFetchComponentCacheAsync()
+ {
+ Person person;
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = await (s.Query().Fetch(o => o.Address).FirstOrDefaultAsync(o => o.Id == 1));
+ AssertFetchComponent(person);
+ await (tx.CommitAsync());
+ }
+
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = await (s.GetAsync(1));
+ AssertFetchComponent(person);
+ // Will reset the cache item
+ person.Name = "Test";
+
+ await (tx.CommitAsync());
+ }
+
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = await (s.GetAsync(1));
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ await (tx.CommitAsync());
+ }
+ }
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public async Task TestFetchAfterPropertyIsInitializedAsync(bool readOnly, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ Person person;
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = await (s.CreateQuery("from Person fetch Address where Id = 1").SetReadOnly(readOnly).UniqueResultAsync(cancellationToken));
+ person.Image = new byte[10];
+ person = await (s.CreateQuery("from Person fetch Image where Id = 1").SetReadOnly(readOnly).UniqueResultAsync(cancellationToken));
+
+ await (tx.CommitAsync(cancellationToken));
+ }
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ Assert.That(person.Image, Has.Length.EqualTo(10));
+
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = await (s.CreateQuery("from Person where Id = 1").SetReadOnly(readOnly).UniqueResultAsync(cancellationToken));
+ person.Image = new byte[1];
+
+ await (tx.CommitAsync(cancellationToken));
+ }
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+ }
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public async Task TestFetchAfterEntityIsInitializedAsync(bool readOnly, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ Person person;
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = await (s.CreateQuery("from Person where Id = 1").SetReadOnly(readOnly).UniqueResultAsync(cancellationToken));
+ var image = person.Image;
+ person = await (s.CreateQuery("from Person fetch Image where Id = 1").SetReadOnly(readOnly).UniqueResultAsync(cancellationToken));
+
+ await (tx.CommitAsync(cancellationToken));
+ }
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+ }
+
+ private static Person GeneratePerson(int i, Person bestFriend)
+ {
+ return new Person
+ {
+ Id = i,
+ Name = $"Person{i}",
+ Address = new Address
+ {
+ City = $"City{i}",
+ Country = $"Country{i}",
+ Continent = GenerateContinent(i)
+ },
+ Image = new byte[i],
+ BestFriend = bestFriend
+ };
+ }
+
+ private static Continent GenerateContinent(int i)
+ {
+ return new Continent
+ {
+ Id = i,
+ Name = $"Continent{i}"
+ };
+ }
+
+ private static Cat GenerateCat(int i, Person owner)
+ {
+ return new Cat
+ {
+ Id = i,
+ Address = new Address
+ {
+ City = owner.Address.City,
+ Country = owner.Address.Country
+ },
+ Image = new byte[i],
+ Name = $"Cat{i}",
+ SecondImage = new byte[i * 2],
+ Owner = owner
+ };
+ }
+
+ private static Dog GenerateDog(int i, Person owner)
+ {
+ return new Dog
+ {
+ Id = i,
+ Address = new Address
+ {
+ City = owner.Address.City,
+ Country = owner.Address.Country
+ },
+ Image = new byte[i * 3],
+ Name = $"Dog{i}",
+ Owner = owner
+ };
+ }
+ }
+}
diff --git a/src/NHibernate.Test/FetchLazyProperties/Address.cs b/src/NHibernate.Test/FetchLazyProperties/Address.cs
new file mode 100644
index 00000000000..4568945fdec
--- /dev/null
+++ b/src/NHibernate.Test/FetchLazyProperties/Address.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NHibernate.Test.FetchLazyProperties
+{
+ public class Address
+ {
+ public string City { get; set; }
+
+ public string Country { get; set; }
+
+ public Continent Continent { get; set; }
+ }
+}
diff --git a/src/NHibernate.Test/FetchLazyProperties/Animal.cs b/src/NHibernate.Test/FetchLazyProperties/Animal.cs
new file mode 100644
index 00000000000..f18a8b76ffe
--- /dev/null
+++ b/src/NHibernate.Test/FetchLazyProperties/Animal.cs
@@ -0,0 +1,18 @@
+
+namespace NHibernate.Test.FetchLazyProperties
+{
+ public abstract class Animal
+ {
+ public virtual int Id { get; set; }
+
+ public virtual int Formula { get; set; }
+
+ public virtual string Name { get; set; }
+
+ public virtual Address Address { get; set; }
+
+ public virtual byte[] Image { get; set; }
+
+ public virtual Person Owner { get; set; }
+ }
+}
diff --git a/src/NHibernate.Test/FetchLazyProperties/Cat.cs b/src/NHibernate.Test/FetchLazyProperties/Cat.cs
new file mode 100644
index 00000000000..790b230983d
--- /dev/null
+++ b/src/NHibernate.Test/FetchLazyProperties/Cat.cs
@@ -0,0 +1,10 @@
+
+namespace NHibernate.Test.FetchLazyProperties
+{
+ public class Cat : Animal
+ {
+ public virtual string SecondFormula { get; set; }
+
+ public virtual byte[] SecondImage { get; set; }
+ }
+}
diff --git a/src/NHibernate.Test/FetchLazyProperties/Continent.cs b/src/NHibernate.Test/FetchLazyProperties/Continent.cs
new file mode 100644
index 00000000000..bf9d0af0b24
--- /dev/null
+++ b/src/NHibernate.Test/FetchLazyProperties/Continent.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NHibernate.Test.FetchLazyProperties
+{
+ public class Continent
+ {
+ public virtual int Id { get; set; }
+
+ public virtual string Name { get; set; }
+ }
+}
diff --git a/src/NHibernate.Test/FetchLazyProperties/Dog.cs b/src/NHibernate.Test/FetchLazyProperties/Dog.cs
new file mode 100644
index 00000000000..1019be4df3b
--- /dev/null
+++ b/src/NHibernate.Test/FetchLazyProperties/Dog.cs
@@ -0,0 +1,7 @@
+
+namespace NHibernate.Test.FetchLazyProperties
+{
+ public class Dog : Animal
+ {
+ }
+}
diff --git a/src/NHibernate.Test/FetchLazyProperties/FetchLazyPropertiesFixture.cs b/src/NHibernate.Test/FetchLazyProperties/FetchLazyPropertiesFixture.cs
new file mode 100644
index 00000000000..2f5bf5442d3
--- /dev/null
+++ b/src/NHibernate.Test/FetchLazyProperties/FetchLazyPropertiesFixture.cs
@@ -0,0 +1,996 @@
+using System;
+using System.Linq;
+using NHibernate.Cache;
+using NHibernate.Cfg;
+using NHibernate.Hql.Ast.ANTLR;
+using NHibernate.Linq;
+using NUnit.Framework;
+using Environment = NHibernate.Cfg.Environment;
+
+namespace NHibernate.Test.FetchLazyProperties
+{
+ [TestFixture]
+ public class FetchLazyPropertiesFixture : TestCase
+ {
+ protected override string MappingsAssembly
+ {
+ get { return "NHibernate.Test"; }
+ }
+
+ protected override string[] Mappings
+ {
+ get { return new[] { "FetchLazyProperties.Mappings.hbm.xml" }; }
+ }
+
+ protected override bool AppliesTo(Dialect.Dialect dialect)
+ {
+ return dialect.SupportsTemporaryTables;
+ }
+
+ protected override void Configure(Configuration configuration)
+ {
+ base.Configure(configuration);
+ configuration.Properties[Environment.CacheProvider] = typeof(HashtableCacheProvider).AssemblyQualifiedName;
+ configuration.Properties[Environment.UseSecondLevelCache] = "true";
+ }
+
+ protected override void OnSetUp()
+ {
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ var currAnimalId = 1;
+ Person lastPerson = null;
+ for (var i = 2; i > 0; i--)
+ {
+ var person = lastPerson = GeneratePerson(i, lastPerson);
+ person.Pets.Add(GenerateCat(currAnimalId++, person));
+ person.Pets.Add(GenerateDog(currAnimalId++, person));
+ s.Save(person);
+ }
+
+ tx.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ s.CreateQuery("delete from Animal").ExecuteUpdate();
+ s.CreateQuery("update Person set BestFriend = null").ExecuteUpdate();
+ s.CreateQuery("delete from Person").ExecuteUpdate();
+ s.CreateQuery("delete from Continent").ExecuteUpdate();
+ tx.Commit();
+ }
+ }
+
+ #region FetchComponent
+
+ [Test]
+ public void TestHqlFetchComponent()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.CreateQuery("from Person fetch Address where Id = 1").UniqueResult();
+ }
+
+ AssertFetchComponent(person);
+ }
+
+ [Test]
+ public void TestLinqFetchComponent()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.Query().Fetch(o => o.Address).FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchComponent(person);
+ }
+
+ private static void AssertFetchComponent(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ Assert.That(person.Address.City, Is.EqualTo("City1"));
+ Assert.That(person.Address.Country, Is.EqualTo("Country1"));
+ }
+
+ #endregion
+
+ #region FetchFormula
+
+ [Test]
+ public void TestHqlFetchFormula()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.CreateQuery("from Person fetch Formula where Id = 1").UniqueResult();
+ }
+
+ AssertFetchFormula(person);
+ }
+
+ [Test]
+ public void TestLinqFetchFormula()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.Query().Fetch(o => o.Formula).FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchFormula(person);
+ }
+
+ private static void AssertFetchFormula(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+
+ Assert.That(person.Formula, Is.EqualTo(1));
+ }
+
+ #endregion
+
+ #region FetchProperty
+
+ [Test]
+ public void TestHqlFetchProperty()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.CreateQuery("from Person fetch Image where Id = 1").UniqueResult();
+ }
+
+ AssertFetchProperty(person);
+ }
+
+ [Test]
+ public void TestLinqFetchProperty()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.Query().Fetch(o => o.Image).FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchProperty(person);
+ }
+
+ private static void AssertFetchProperty(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ Assert.That(person.Image, Has.Length.EqualTo(1));
+ }
+
+ #endregion
+
+
+ #region FetchComponentAndFormulaTwoQueryReadOnly
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public void TestHqlFetchComponentAndFormulaTwoQueryReadOnly(bool readOnly)
+ {
+ Person person;
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = s.CreateQuery("from Person fetch Address where Id = 1").SetReadOnly(readOnly).UniqueResult();
+ person = s.CreateQuery("from Person fetch Formula where Id = 1").SetReadOnly(readOnly).UniqueResult();
+
+ tx.Commit();
+ }
+
+ AssertFetchComponentAndFormulaTwoQuery(person);
+ }
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public void TestLinqFetchComponentAndFormulaTwoQuery(bool readOnly)
+ {
+ Person person;
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = s.Query().Fetch(o => o.Address).WithOptions(o => o.SetReadOnly(readOnly)).FirstOrDefault(o => o.Id == 1);
+ person = s.Query().Fetch(o => o.Formula).WithOptions(o => o.SetReadOnly(readOnly)).FirstOrDefault(o => o.Id == 1);
+
+ tx.Commit();
+ }
+
+ AssertFetchComponentAndFormulaTwoQuery(person);
+ }
+
+ private static void AssertFetchComponentAndFormulaTwoQuery(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+
+ Assert.That(person.Address.City, Is.EqualTo("City1"));
+ Assert.That(person.Address.Country, Is.EqualTo("Country1"));
+ Assert.That(person.Formula, Is.EqualTo(1));
+ }
+
+ #endregion
+
+ #region FetchAllProperties
+
+ [Test]
+ public void TestHqlFetchAllProperties()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.CreateQuery("from Person fetch all properties where Id = 1").UniqueResult();
+ }
+
+ AssertFetchAllProperties(person);
+ }
+
+ [Test]
+ public void TestLinqFetchAllProperties()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.Query().FetchLazyProperties().FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchAllProperties(person);
+ }
+
+ private static void AssertFetchAllProperties(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+
+ Assert.That(person.Image, Has.Length.EqualTo(1));
+ Assert.That(person.Address.City, Is.EqualTo("City1"));
+ Assert.That(person.Address.Country, Is.EqualTo("Country1"));
+ Assert.That(person.Formula, Is.EqualTo(1));
+ }
+
+ #endregion
+
+ #region FetchAllPropertiesIndividually
+
+ [Test]
+ public void TestHqlFetchAllPropertiesIndividually()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.CreateQuery("from Person fetch Image fetch Address fetch Formula fetch Image where Id = 1").UniqueResult();
+ }
+
+ AssertFetchAllProperties(person);
+ }
+
+ [Test]
+ public void TestLinqFetchAllPropertiesIndividually()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.Query().Fetch(o => o.Image).Fetch(o => o.Address).Fetch(o => o.Formula).FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchAllProperties(person);
+ }
+
+ #endregion
+
+ #region FetchFormulaAndManyToOneComponent
+
+ [Test]
+ public void TestHqlFetchFormulaAndManyToOneComponent()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.CreateQuery("from Person p fetch p.Formula left join fetch p.BestFriend bf fetch bf.Address where p.Id = 1")
+ .UniqueResult();
+ }
+
+ AssertFetchFormulaAndManyToOneComponent(person);
+ }
+
+ [Test]
+ public void TestLinqFetchFormulaAndManyToOneComponent()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.Query()
+ .Fetch(o => o.Formula)
+ .Fetch(o => o.BestFriend).ThenFetch(o => o.Address)
+ .FirstOrDefault(o => o.Id == 1);
+
+ }
+
+ AssertFetchFormulaAndManyToOneComponent(person);
+ }
+
+ private static void AssertFetchFormulaAndManyToOneComponent(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+
+ Assert.That(NHibernateUtil.IsInitialized(person.BestFriend), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Formula"), Is.False);
+
+ Assert.That(person.Formula, Is.EqualTo(1));
+ Assert.That(person.BestFriend.Address.City, Is.EqualTo("City2"));
+ Assert.That(person.BestFriend.Address.Country, Is.EqualTo("Country2"));
+ }
+
+ #endregion
+
+ #region FetchFormulaAndManyToOneComponentList
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public void TestHqlFetchFormulaAndManyToOneComponentList(bool descending)
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.CreateQuery("from Person p fetch p.Formula left join fetch p.BestFriend bf fetch bf.Address order by p.Id" + (descending ? " desc" : ""))
+ .List().FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchFormulaAndManyToOneComponentList(person);
+ }
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public void TestLinqFetchFormulaAndManyToOneComponentList(bool descending)
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ IQueryable query = s.Query()
+ .Fetch(o => o.Formula)
+ .Fetch(o => o.BestFriend).ThenFetch(o => o.Address);
+ query = descending ? query.OrderByDescending(o => o.Id) : query.OrderBy(o => o.Id);
+ person = query
+ .ToList()
+ .FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchFormulaAndManyToOneComponentList(person);
+ }
+
+ private static void AssertFetchFormulaAndManyToOneComponentList(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+
+ Assert.That(NHibernateUtil.IsInitialized(person.BestFriend), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Formula"), Is.True);
+
+ Assert.That(person.Formula, Is.EqualTo(1));
+ Assert.That(person.BestFriend.Address.City, Is.EqualTo("City2"));
+ Assert.That(person.BestFriend.Address.Country, Is.EqualTo("Country2"));
+ }
+
+ #endregion
+
+ #region FetchManyToOneAllProperties
+
+ [Test]
+ public void TestHqlFetchManyToOneAllProperties()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.CreateQuery("from Person p left join fetch p.BestFriend fetch all properties")
+ .List().FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchManyToOneAllProperties(person);
+ }
+
+ [Test]
+ public void TestLinqFetchManyToOneAllProperties()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.Query()
+ .Fetch(o => o.BestFriend).FetchLazyProperties()
+ .ToList()
+ .FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchManyToOneAllProperties(person);
+ }
+
+ private static void AssertFetchManyToOneAllProperties(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ Assert.That(NHibernateUtil.IsInitialized(person.BestFriend), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Image"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person.BestFriend, "Formula"), Is.True);
+
+ Assert.That(person.BestFriend.Formula, Is.EqualTo(2));
+ Assert.That(person.BestFriend.Address.City, Is.EqualTo("City2"));
+ Assert.That(person.BestFriend.Address.Country, Is.EqualTo("Country2"));
+ Assert.That(person.BestFriend.Image, Has.Length.EqualTo(2));
+ }
+
+ #endregion
+
+ #region FetchFormulaAndOneToManyComponent
+
+ [Test]
+ public void TestHqlFetchFormulaAndOneToManyComponent()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.CreateQuery("from Person p fetch p.Formula left join fetch p.Dogs dog fetch dog.Address where p.Id = 1")
+ .List()
+ .FirstOrDefault();
+ }
+
+ AssertFetchFormulaAndOneToManyComponent(person);
+ }
+
+ [Test]
+ public void TestLinqFetchFormulaAndOneToManyComponent()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.Query()
+ .Fetch(o => o.Formula)
+ .FetchMany(o => o.Dogs).ThenFetch(o => o.Address)
+ .Where(o => o.Id == 1)
+ .ToList()
+ .FirstOrDefault();
+ }
+
+ AssertFetchFormulaAndOneToManyComponent(person);
+ }
+
+ private static void AssertFetchFormulaAndOneToManyComponent(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+
+ Assert.That(NHibernateUtil.IsInitialized(person.Dogs), Is.True);
+ Assert.That(NHibernateUtil.IsInitialized(person.BestFriend), Is.False);
+ Assert.That(NHibernateUtil.IsInitialized(person.Pets), Is.False);
+
+ Assert.That(person.Formula, Is.EqualTo(1));
+ Assert.That(person.Dogs, Has.Count.EqualTo(1));
+ foreach (var dog in person.Dogs)
+ {
+ Assert.That(NHibernateUtil.IsPropertyInitialized(dog, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(dog, "Formula"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(dog, "Address"), Is.True);
+
+ Assert.That(dog.Address.City, Is.EqualTo("City1"));
+ Assert.That(dog.Address.Country, Is.EqualTo("Country1"));
+ }
+ }
+
+ #endregion
+
+ #region FetchOneToManyProperty
+
+ [Test]
+ public void TestHqlFetchOneToManyProperty()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.CreateQuery("from Person p left join fetch p.Cats cat fetch cat.SecondImage where p.Id = 1")
+ .List()
+ .FirstOrDefault();
+ }
+
+ AssertFetchOneToManyProperty(person);
+ }
+
+ [Test]
+ public void TestLinqFetchOneToManyProperty()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.Query()
+ .FetchMany(o => o.Cats).ThenFetch(o => o.SecondImage)
+ .Where(o => o.Id == 1)
+ .ToList()
+ .FirstOrDefault();
+ }
+
+ AssertFetchOneToManyProperty(person);
+ }
+
+ private static void AssertFetchOneToManyProperty(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ Assert.That(NHibernateUtil.IsInitialized(person.BestFriend), Is.False);
+ Assert.That(NHibernateUtil.IsInitialized(person.Pets), Is.False);
+ Assert.That(NHibernateUtil.IsInitialized(person.Cats), Is.True);
+
+ Assert.That(person.Cats, Has.Count.EqualTo(1));
+ foreach (var cat in person.Cats)
+ {
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Formula"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondImage"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondFormula"), Is.False);
+
+ Assert.That(cat.SecondImage, Has.Length.EqualTo(6));
+ }
+ }
+
+ #endregion
+
+ #region FetchNotMappedProperty
+
+ [Test]
+ public void TestHqlFetchNotMappedProperty()
+ {
+ using (var s = OpenSession())
+ {
+ Assert.Throws(
+ () =>
+ {
+ var person = s.CreateQuery("from Person p fetch p.BirthYear where p.Id = 1").UniqueResult();
+ });
+ }
+ }
+
+ [Test]
+ public void TestLinqFetchNotMappedProperty()
+ {
+ using (var s = OpenSession())
+ {
+ Assert.Throws(
+ () =>
+ {
+ var person = s.Query().Fetch(o => o.BirthYear).FirstOrDefault(o => o.Id == 1);
+ });
+ }
+ }
+
+ #endregion
+
+ #region FetchComponentManyToOne
+
+ [Test]
+ public void TestHqlFetchComponentManyToOne()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.CreateQuery("from Person p fetch p.Address left join fetch p.Address.Continent where p.Id = 1").UniqueResult();
+ }
+
+ AssertFetchComponentManyToOne(person);
+ }
+
+ [Test]
+ public void TestLinqFetchComponentManyToOne()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.Query().Fetch(o => o.Address).ThenFetch(o => o.Continent).FirstOrDefault(o => o.Id == 1);
+ }
+
+ AssertFetchComponentManyToOne(person);
+ }
+
+ private static void AssertFetchComponentManyToOne(Person person)
+ {
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ Assert.That(NHibernateUtil.IsInitialized(person.Address.Continent), Is.True);
+
+ Assert.That(person.Address.City, Is.EqualTo("City1"));
+ Assert.That(person.Address.Country, Is.EqualTo("Country1"));
+ Assert.That(person.Address.Continent.Name, Is.EqualTo("Continent1"));
+ }
+
+ #endregion
+
+ #region FetchSubClassFormula
+
+ [Test]
+ public void TestHqlFetchSubClassFormula()
+ {
+ Animal animal;
+ using (var s = OpenSession())
+ {
+ animal = s.CreateQuery("from Animal a fetch a.SecondFormula where a.Id = 1").UniqueResult();
+ }
+
+ AssertFetchSubClassFormula(animal);
+ }
+
+ [Test]
+ public void TestLinqFetchSubClassFormula()
+ {
+ Animal animal;
+ using (var s = OpenSession())
+ {
+ animal = s.Query().Fetch(o => ((Cat) o).SecondFormula).First(o => o.Id == 1);
+ }
+
+ AssertFetchSubClassFormula(animal);
+ }
+
+ private static void AssertFetchSubClassFormula(Animal animal)
+ {
+ Assert.That(animal, Is.AssignableTo(typeof(Cat)));
+ var cat = (Cat) animal;
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondFormula"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondImage"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Formula"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Image"), Is.False);
+ }
+
+ #endregion
+
+ #region FetchSubClassProperty
+
+ [Test]
+ public void TestHqlFetchSubClassProperty()
+ {
+ Animal animal;
+ using (var s = OpenSession())
+ {
+ animal = s.CreateQuery("from Animal a fetch a.SecondImage where a.Id = 1").UniqueResult();
+ }
+
+ AssertFetchSubClassProperty(animal);
+ }
+
+ [Test]
+ public void TestLinqFetchSubClassProperty()
+ {
+ Animal animal;
+ using (var s = OpenSession())
+ {
+ animal = s.Query().Fetch(o => ((Cat) o).SecondImage).First(o => o.Id == 1);
+ }
+
+ AssertFetchSubClassProperty(animal);
+ }
+
+ private static void AssertFetchSubClassProperty(Animal animal)
+ {
+ Assert.That(animal, Is.AssignableTo(typeof(Cat)));
+ var cat = (Cat) animal;
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondFormula"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondImage"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Formula"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Image"), Is.False);
+ }
+
+ #endregion
+
+ #region FetchSubClassAllProperty
+
+ [Test]
+ public void TestHqlFetchSubClassAllProperties()
+ {
+ Animal animal;
+ using (var s = OpenSession())
+ {
+ animal = s.CreateQuery("from Animal a fetch all properties where a.Id = 1").UniqueResult();
+ }
+
+ AssertFetchSubClassAllProperties(animal);
+ }
+
+ [Test]
+ public void TestLinqFetchSubClassAllProperties()
+ {
+ Animal animal;
+ using (var s = OpenSession())
+ {
+ animal = s.Query().FetchLazyProperties().First(o => o.Id == 1);
+ }
+
+ AssertFetchSubClassAllProperties(animal);
+ }
+
+ private static void AssertFetchSubClassAllProperties(Animal animal)
+ {
+ Assert.That(animal, Is.AssignableTo(typeof(Cat)));
+ var cat = (Cat) animal;
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondFormula"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "SecondImage"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Formula"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(cat, "Image"), Is.True);
+ }
+
+ #endregion
+
+ #region FetchAllPropertiesWithFetchProperty
+
+ [Test]
+ public void TestHqlFetchAllPropertiesWithFetchProperty()
+ {
+ using (var s = OpenSession())
+ {
+ Assert.Throws(
+ () =>
+ {
+ var person = s.CreateQuery("from Person p fetch p.Address fetch all properties where p.Id = 1").UniqueResult();
+ });
+ Assert.Throws(
+ () =>
+ {
+ var person = s.CreateQuery("from Person p fetch all properties fetch p.Address where p.Id = 1").UniqueResult();
+ });
+ }
+ }
+
+ [Test]
+ public void TestLinqFetchAllPropertiesWithFetchProperty()
+ {
+ using (var s = OpenSession())
+ {
+ Assert.Throws(
+ () =>
+ {
+ var person = s.Query().Fetch(o => o.Address).FetchLazyProperties().FirstOrDefault(o => o.Id == 1);
+ });
+ Assert.Throws(
+ () =>
+ {
+ var person = s.Query().FetchLazyProperties().Fetch(o => o.Address).FirstOrDefault(o => o.Id == 1);
+ });
+ }
+ }
+
+ #endregion
+
+ [Test]
+ public void TestHqlFetchComponentAlias()
+ {
+ Person person;
+ using (var s = OpenSession())
+ {
+ person = s.CreateQuery("from Person p fetch p.Address where p.Id = 1").UniqueResult();
+ }
+
+ AssertFetchComponent(person);
+ }
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public void TestFetchComponentAndFormulaTwoQueryCache(bool readOnly)
+ {
+ TestLinqFetchComponentAndFormulaTwoQuery(readOnly);
+
+ Person person;
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = s.Get(1);
+
+ tx.Commit();
+ }
+
+ AssertFetchComponentAndFormulaTwoQuery(person);
+ }
+
+ [Test]
+ public void TestFetchComponentCache()
+ {
+ Person person;
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = s.Query().Fetch(o => o.Address).FirstOrDefault(o => o.Id == 1);
+ AssertFetchComponent(person);
+ tx.Commit();
+ }
+
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = s.Get(1);
+ AssertFetchComponent(person);
+ // Will reset the cache item
+ person.Name = "Test";
+
+ tx.Commit();
+ }
+
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = s.Get(1);
+ Assert.That(person, Is.Not.Null);
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ tx.Commit();
+ }
+ }
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public void TestFetchAfterPropertyIsInitialized(bool readOnly)
+ {
+ Person person;
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = s.CreateQuery("from Person fetch Address where Id = 1").SetReadOnly(readOnly).UniqueResult();
+ person.Image = new byte[10];
+ person = s.CreateQuery("from Person fetch Image where Id = 1").SetReadOnly(readOnly).UniqueResult();
+
+ tx.Commit();
+ }
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+
+ Assert.That(person.Image, Has.Length.EqualTo(10));
+
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = s.CreateQuery("from Person where Id = 1").SetReadOnly(readOnly).UniqueResult();
+ person.Image = new byte[1];
+
+ tx.Commit();
+ }
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.False);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.False);
+ }
+
+ [TestCase(true)]
+ [TestCase(false)]
+ public void TestFetchAfterEntityIsInitialized(bool readOnly)
+ {
+ Person person;
+ using (var s = OpenSession())
+ using (var tx = s.BeginTransaction())
+ {
+ person = s.CreateQuery("from Person where Id = 1").SetReadOnly(readOnly).UniqueResult();
+ var image = person.Image;
+ person = s.CreateQuery("from Person fetch Image where Id = 1").SetReadOnly(readOnly).UniqueResult();
+
+ tx.Commit();
+ }
+
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Image"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Address"), Is.True);
+ Assert.That(NHibernateUtil.IsPropertyInitialized(person, "Formula"), Is.True);
+ }
+
+ private static Person GeneratePerson(int i, Person bestFriend)
+ {
+ return new Person
+ {
+ Id = i,
+ Name = $"Person{i}",
+ Address = new Address
+ {
+ City = $"City{i}",
+ Country = $"Country{i}",
+ Continent = GenerateContinent(i)
+ },
+ Image = new byte[i],
+ BestFriend = bestFriend
+ };
+ }
+
+ private static Continent GenerateContinent(int i)
+ {
+ return new Continent
+ {
+ Id = i,
+ Name = $"Continent{i}"
+ };
+ }
+
+ private static Cat GenerateCat(int i, Person owner)
+ {
+ return new Cat
+ {
+ Id = i,
+ Address = new Address
+ {
+ City = owner.Address.City,
+ Country = owner.Address.Country
+ },
+ Image = new byte[i],
+ Name = $"Cat{i}",
+ SecondImage = new byte[i * 2],
+ Owner = owner
+ };
+ }
+
+ private static Dog GenerateDog(int i, Person owner)
+ {
+ return new Dog
+ {
+ Id = i,
+ Address = new Address
+ {
+ City = owner.Address.City,
+ Country = owner.Address.Country
+ },
+ Image = new byte[i * 3],
+ Name = $"Dog{i}",
+ Owner = owner
+ };
+ }
+ }
+}
diff --git a/src/NHibernate.Test/FetchLazyProperties/Mappings.hbm.xml b/src/NHibernate.Test/FetchLazyProperties/Mappings.hbm.xml
new file mode 100644
index 00000000000..e832dbca5ae
--- /dev/null
+++ b/src/NHibernate.Test/FetchLazyProperties/Mappings.hbm.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/NHibernate.Test/FetchLazyProperties/Person.cs b/src/NHibernate.Test/FetchLazyProperties/Person.cs
new file mode 100644
index 00000000000..4e13bddff23
--- /dev/null
+++ b/src/NHibernate.Test/FetchLazyProperties/Person.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+
+namespace NHibernate.Test.FetchLazyProperties
+{
+ public class Person
+ {
+ public virtual int Id { get; set; }
+
+ public virtual string Name { get; set; }
+
+ public virtual int Formula { get; set; }
+
+ public virtual Address Address { get; set; }
+
+ public virtual byte[] Image { get; set; }
+
+ public virtual Person BestFriend { get; set; }
+
+ // Not mapped property
+ public virtual int BirthYear { get; set; }
+
+ public virtual ISet Pets { get; set; } = new HashSet();
+
+ public virtual ISet Cats { get; set; } = new HashSet();
+
+ public virtual ISet Dogs { get; set; } = new HashSet();
+ }
+}
diff --git a/src/NHibernate/Async/Impl/MultiCriteriaImpl.cs b/src/NHibernate/Async/Impl/MultiCriteriaImpl.cs
index 66e293c3b08..3f063cf00e6 100644
--- a/src/NHibernate/Async/Impl/MultiCriteriaImpl.cs
+++ b/src/NHibernate/Async/Impl/MultiCriteriaImpl.cs
@@ -152,6 +152,7 @@ private async Task GetResultsFromDatabaseAsync(IList results, CancellationToken
stopWatch.Start();
}
int rowCount = 0;
+ var cacheBatcher = new CacheBatcher(session);
try
{
@@ -184,7 +185,8 @@ private async Task GetResultsFromDatabaseAsync(IList results, CancellationToken
object o =
await (loader.GetRowFromResultSetAsync(reader, session, queryParameters, loader.GetLockModes(queryParameters.LockModes),
- null, hydratedObjects[i], keys, true, cancellationToken)).ConfigureAwait(false);
+ null, hydratedObjects[i], keys, true,
+ (persister, data) => cacheBatcher.AddToBatch(persister, data), cancellationToken)).ConfigureAwait(false);
if (createSubselects[i])
{
subselectResultKeys[i].Add(keys);
@@ -200,13 +202,15 @@ private async Task GetResultsFromDatabaseAsync(IList results, CancellationToken
for (int i = 0; i < loaders.Count; i++)
{
CriteriaLoader loader = loaders[i];
- await (loader.InitializeEntitiesAndCollectionsAsync(hydratedObjects[i], reader, session, session.DefaultReadOnly, cancellationToken: cancellationToken)).ConfigureAwait(false);
+ await (loader.InitializeEntitiesAndCollectionsAsync(hydratedObjects[i], reader, session, session.DefaultReadOnly, cacheBatcher, cancellationToken)).ConfigureAwait(false);
if (createSubselects[i])
{
loader.CreateSubselects(subselectResultKeys[i], parameters[i], session);
}
}
+
+ await (cacheBatcher.ExecuteBatchAsync(cancellationToken)).ConfigureAwait(false);
}
}
catch (OperationCanceledException) { throw; }
diff --git a/src/NHibernate/Async/Impl/MultiQueryImpl.cs b/src/NHibernate/Async/Impl/MultiQueryImpl.cs
index 93cf48d59ad..b65ead8cf26 100644
--- a/src/NHibernate/Async/Impl/MultiQueryImpl.cs
+++ b/src/NHibernate/Async/Impl/MultiQueryImpl.cs
@@ -89,6 +89,7 @@ protected async Task> DoListAsync(CancellationToken cancellationTok
var hydratedObjects = new List