public void PersistentStateAccessorTest() { var domain = BuildDomain(); using (var session = domain.OpenSession()) { Key entityKey; using (var tx = session.OpenTransaction()) { var entity = new Simple(session) { Value = Guid.NewGuid().ToString() }; entityKey = entity.Key; tx.Complete(); } using (var tx = session.OpenTransaction()) { var entity = session.Query.Single <Simple>(entityKey); var entityState = DirectStateAccessor.Get(entity); var valueFieldState = entityState.GetFieldState("Value"); Assert.AreEqual(PersistentFieldState.Loaded, valueFieldState); entity.Value += "Modified"; valueFieldState = entityState.GetFieldState("Value"); Assert.AreEqual(PersistentFieldState.Modified, valueFieldState); tx.Complete(); } } }
public void EntitySetAccessorTest() { var domain = BuildDomain(); using (var session = domain.OpenSession()) { Key containerKey; Key firstContainedKey; using (var tx = session.OpenTransaction()) { var container = new Container(session); containerKey = container.Key; container.Entities.Add(new Simple(session)); firstContainedKey = container.Entities.Single().Key; container.Entities.Add(new Simple(session)); container.Entities.Add(new Simple(session)); tx.Complete(); } using (var tx = session.OpenTransaction()) { var container = session.Query.Single <Container>(containerKey); var entitySetState = DirectStateAccessor.Get(container.Entities); Assert.IsFalse(entitySetState.IsFullyLoaded); foreach (var simple in container.Entities) { break; // To do nothing, but just call GetEnumerator() } Assert.IsTrue(entitySetState.IsFullyLoaded); // Enumeration attempt leads to full loading Assert.IsTrue(entitySetState.IsCountAvailable); // So Count is available as well Assert.AreEqual(3, entitySetState.Count); Assert.IsTrue(entitySetState.Contains(firstContainedKey)); } } }
public void CombinedTest() { var domain = BuildDomain(); using (var session = domain.OpenSession()) { var directSql = session.Services.Demand <DirectSqlAccessor>(); using (var t = session.OpenTransaction()) { var article = new Article(session) { Title = "Some title", Content = "Some content" }; session.SaveChanges(); // Ensures changes are flushed // Article is created: Assert.IsFalse(article.IsRemoved); // Direct SQL command execution var command = session.Services.Demand <DirectSqlAccessor>().CreateCommand(); command.CommandText = "DELETE FROM [dbo].[DirectSqlAccessorTest.Article];"; command.ExecuteNonQuery(); // Let's invalidate session cache after this DirectStateAccessor.Get(session).Invalidate(); // Entity is really removed: Assert.IsTrue(article.IsRemoved); Assert.IsNull(session.Query.SingleOrDefault(article.Key)); t.Complete(); } } }
public async Task MultipleBatchesAsyncTest() { var config = DomainConfigurationFactory.CreateWithoutSessionConfigurations(); config.UpgradeMode = DomainUpgradeMode.Recreate; config.Types.Register(typeof(Person).Assembly, typeof(Person).Namespace); var domain = Domain.Build(config); int count = 1000; using (var session = domain.OpenSession()) using (var transactionScope = session.OpenTransaction()){ var random = new Random(10); for (int i = 0; i < count; i++) { new Person(session) { Name = i.ToString(), Photo = new[] { (byte)(i % 256) } } } ; var persons = session.Query.All <Person>().OrderBy(p => p.Id).ToArray(); for (int i = 0; i < count; i++) { var person = persons[i]; if (random.Next(5) > 0) { person.Manager = persons[random.Next(count)]; } } transactionScope.Complete(); } using (var session = domain.OpenSession()) using (var transactionScope = session.OpenTransaction()) { var prefetchedPersons = ( from person in session.Query.All <Person>() orderby person.Name select person) .Take(100) .Prefetch(p => p.Photo) // Lazy load field .Prefetch(p => p.Employees // EntitySet Employees .Prefetch(e => e.Photo)) // and lazy load field of each of its items .Prefetch(p => p.Manager) // Referenced entity .AsAsync(); foreach (var person in await prefetchedPersons) { Assert.IsTrue(DirectStateAccessor.Get(person).GetFieldState("Photo") == PersistentFieldState.Loaded); Assert.IsTrue(DirectStateAccessor.Get(person).GetFieldState("Manager") == PersistentFieldState.Loaded); Assert.IsTrue(DirectStateAccessor.Get(person.Employees).IsFullyLoaded); foreach (var employee in person.Employees) { Assert.IsTrue(DirectStateAccessor.Get(employee).GetFieldState("Photo") == PersistentFieldState.Loaded); } } transactionScope.Complete(); } } }
public int Execute() { EnsureTransactionIsStarted(); Session.SaveChanges(); int value = ExecuteInternal(); DirectStateAccessor.Get(QueryProvider.Session).Invalidate(); return(value); }
public async Task <int> ExecuteAsync(CancellationToken token = default) { EnsureTransactionIsStarted(); await QueryProvider.Session.SaveChangesAsync(token).ConfigureAwait(false); var value = await ExecuteInternalAsync(token).ConfigureAwait(false); DirectStateAccessor.Get(QueryProvider.Session).Invalidate(); return(value); }
public async Task MultipleBatchesAsyncTest() { var count = 1000; await using (var session = await Domain.OpenSessionAsync()) using (var transactionScope = session.OpenTransaction()){ var people = new Person[count]; for (var i = 0; i < count; i++) { people[i] = new Person(session) { Name = i.ToString(), Photo = new[] { (byte)(i % 256) } }; } session.SaveChanges(); var random = new Random(10); for (var i = 0; i < count; i++) { var person = people[i]; if (random.Next(5) > 0) { person.Manager = people[random.Next(count)]; } } transactionScope.Complete(); } await using (var session = await Domain.OpenSessionAsync()) using (var transactionScope = session.OpenTransaction()) { var prefetchedPeople = ( from person in session.Query.All <Person>() orderby person.Name select person) .Take(100) .Prefetch(p => p.Photo) // Lazy load field .Prefetch(p => p.Employees // EntitySet Employees .Prefetch(e => e.Photo)) // and lazy load field of each of its items .Prefetch(p => p.Manager); // Referenced entity await foreach (var person in prefetchedPeople.AsAsyncEnumerable()) { var accessor = DirectStateAccessor.Get(person); Assert.That(accessor.GetFieldState("Photo"), Is.EqualTo(PersistentFieldState.Loaded)); Assert.That(accessor.GetFieldState("Manager"), Is.EqualTo(PersistentFieldState.Loaded)); Assert.IsTrue(DirectStateAccessor.Get(person.Employees).IsFullyLoaded); foreach (var employee in person.Employees) { Assert.That(DirectStateAccessor.Get(employee).GetFieldState("Photo"), Is.EqualTo(PersistentFieldState.Loaded)); } } transactionScope.Complete(); } }
public async Task CachedQueryAsyncTest() { await using (var session = await Domain.OpenSessionAsync()) using (var transactionScope = session.OpenTransaction()) { var employee = new Person(session) { Name = "Employee", Photo = new byte[] { 8, 0 } }; var manager = new Person(session) { Name = "Manager", Photo = new byte[] { 8, 0 } }; _ = manager.Employees.Add(employee); transactionScope.Complete(); } await using (var session = await Domain.OpenSessionAsync()) // no session activation! using (var transactionScope = session.OpenTransaction()) { var people = (await session.Query.ExecuteAsync(q => q.All <Person>())) .Prefetch(p => p.Photo) // Lazy load field .Prefetch(p => p.Employees // EntitySet Employees .Prefetch(e => e.Photo)) // and lazy load field of each of its items .Prefetch(p => p.Manager); // Referenced entity foreach (var person in people) { // some code here... } transactionScope.Complete(); } await using (var session = await Domain.OpenSessionAsync()) // no session activation! using (var transactionScope = session.OpenTransaction()) { var people = (await session.Query.ExecuteAsync(q => q.All <Person>())) .Prefetch(p => p.Photo) // Lazy load field .Prefetch(p => p.Employees.Prefetch(e => e.Photo)) // EntitySet Employees and lazy load field of each of its items with the limit on number of items to be loaded .Prefetch(p => p.Manager.Photo); // Referenced entity and lazy load field for each of them await foreach (var person in people.AsAsyncEnumerable()) { var accessor = DirectStateAccessor.Get(person); Assert.That(accessor.GetFieldState("Photo"), Is.EqualTo(PersistentFieldState.Loaded)); Assert.That(accessor.GetFieldState("Manager"), Is.EqualTo(PersistentFieldState.Loaded)); if (person.ManagerKey != null) { Assert.IsNotNull(DirectStateAccessor.Get(session)[person.ManagerKey]); Assert.That(DirectStateAccessor.Get(person.Manager).GetFieldState("Photo"), Is.EqualTo(PersistentFieldState.Loaded)); } // some code here... } transactionScope.Complete(); } }
public void UnexpectedLazyPropertyReadBugTest() { using (var session = Domain.OpenSession()) using (var tx = session.OpenTransaction()) { var book = Query.All <CoolBook>().Where(b => b.Key == key).Single(); var psa = DirectStateAccessor.Get(book); Assert.IsTrue(0 == (psa.GetFieldState("LazyPopularity") & PersistentFieldState.Loaded)); book.OtherCoolBooks.Add(book); // (1) Assert.IsTrue(0 == (psa.GetFieldState("LazyPopularity") & PersistentFieldState.Loaded)); session.SaveChanges(); book.Remove(); // Fails, but only if (1) is enabled! Assert.IsTrue(0 == (psa.GetFieldState("LazyPopularity") & PersistentFieldState.Loaded)); } }
public void SessionStateAccessorTest() { var domain = BuildDomain(); using (var session = domain.OpenSession()) { Key entityKey; string originalValue; using (var tx = session.OpenTransaction()) { var entity = new Simple(session) { Value = Guid.NewGuid().ToString() }; entityKey = entity.Key; session.SaveChanges(); // Let's get session cache accessor var sessionState = DirectStateAccessor.Get(session); // Get the number of cached entities Assert.AreEqual(1, sessionState.Count); // Enumerate cached entites foreach (var e in sessionState) { if (e == entity) { continue; } Assert.Fail(); } // Let's remember the value & change it originalValue = entity.Value; entity.Value += "Modified"; // Clear cached state of all the entities in session sessionState.Invalidate(); // The field value hasn't been modified due to invalidation Assert.AreEqual(originalValue, entity.Value); tx.Complete(); } } }
public void SqlStorageTest() { Require.ProviderIs(StorageProvider.SqlServer); using (var session = Domain.OpenSession()) { var directSql = session.Services.Demand <DirectSqlAccessor>(); Assert.IsNull(directSql.Transaction); using (var t = session.OpenTransaction()) { var article = new Article { Title = "Some title", Content = "Some content" }; session.SaveChanges(); // Now both are definitely not null Assert.IsNotNull(directSql.Connection); Assert.IsNotNull(directSql.Transaction); var command = session.Services.Demand <DirectSqlAccessor>().CreateCommand(); command.CommandText = "DELETE FROM [dbo].[DirectSqlTest.Article];"; command.ExecuteNonQuery(); // Cache invalidation (~ like on rollback, but w/o rollback) DirectStateAccessor.Get(session).Invalidate(); var anotherArticle = new Article { Title = "Another title", Content = "Another content" }; session.SaveChanges(); AssertEx.ThrowsInvalidOperationException(() => Assert.IsNotNull(article.Content)); Assert.AreEqual(1, session.Query.All <Article>().Count()); Assert.IsNotNull(anotherArticle.Content); t.Complete(); } } }
public void MainTest() { using (var session = Domain.OpenSession()) using (var transactionScope = session.OpenTransaction()) { var employee = new Person(session) { Name = "Employee", Photo = new byte[] { 8, 0 } }; var manager = new Person(session) { Name = "Manager", Photo = new byte[] { 8, 0 } }; _ = manager.Employees.Add(employee); transactionScope.Complete(); } using (var session = Domain.OpenSession()) using (var transactionScope = session.OpenTransaction()) { var people = session.Query.All <Person>() .Prefetch(p => p.Photo) // Lazy load field .Prefetch(p => p.Employees // EntitySet Employees .Prefetch(e => e.Photo)) // and lazy load field of each of its items .Prefetch(p => p.Manager); // Referenced entity foreach (var person in people) { // some code here... } transactionScope.Complete(); } using (var session = Domain.OpenSession()) using (var transactionScope = session.OpenTransaction()) { var personIds = session.Query.All <Person>().Select(p => p.Id); var prefetchedPeople = session.Query.Many <Person, int>(personIds) .Prefetch(p => new { p.Photo, p.Manager }) // Lazy load field and Referenced entity .Prefetch(p => p.Employees // EntitySet Employees .Prefetch(e => new { e.Photo, e.Manager })); // and lazy load field and referenced entity of each of its items foreach (var person in prefetchedPeople) { // some code here... } transactionScope.Complete(); } using (var session = Domain.OpenSession()) using (var transactionScope = session.OpenTransaction()) { var people = session.Query.All <Person>() .Prefetch(p => p.Photo) // Lazy load field .Prefetch(p => p.Employees.Prefetch(e => e.Photo)) // EntitySet Employees and lazy load field of each of its items with the limit on number of items to be loaded .Prefetch(p => p.Manager.Photo); // Referenced entity and lazy load field for each of them foreach (var person in people) { var accessor = DirectStateAccessor.Get(person); Assert.That(accessor.GetFieldState("Photo"), Is.EqualTo(PersistentFieldState.Loaded)); Assert.That(accessor.GetFieldState("Manager"), Is.EqualTo(PersistentFieldState.Loaded)); if (person.ManagerKey != null) { Assert.IsNotNull(DirectStateAccessor.Get(session)[person.ManagerKey]); Assert.That(DirectStateAccessor.Get(person.Manager).GetFieldState("Photo"), Is.EqualTo(PersistentFieldState.Loaded)); } // some code here... } transactionScope.Complete(); } }
public void StandardTest() { using (var session = Domain.OpenSession()) using (var tx = session.OpenTransaction()) { var sessionStateAccessor = DirectStateAccessor.Get(session); var book1 = new Book() { Title = "Book 1" }; var book2 = new Book() { Title = "Book" }; book1.RelatedBooks.CollectionChanged += RelatedBooks_CollectionChanged; book2.PropertyChanged += Book_PropertyChanged; ResetLastXxx(); book2.Title = "Book 2"; Assert.AreEqual("Title", lastChangedProperty); Assert.AreSame(book2, lastSenderObject); ResetLastXxx(); book1.RelatedBooks.Add(book2); Assert.AreEqual(NotifyCollectionChangedAction.Add, lastChangeAction); Assert.AreSame(book1.RelatedBooks, lastSenderCollection); { // Test 1 ResetLastXxx(); book1.RelatedBooks.Remove(book2); // "Reset", coz collection is considered as not fully loaded #if DEBUG Assert.AreEqual(NotifyCollectionChangedAction.Reset, lastChangeAction); #else Assert.AreEqual(NotifyCollectionChangedAction.Remove, lastChangeAction); #endif Assert.AreSame(book1.RelatedBooks, lastSenderCollection); } // Restoring removed item book1.RelatedBooks.Add(book2); // Let's fully load the collection var bookCount = book1.RelatedBooks.Count; { // Test 2 ResetLastXxx(); book1.RelatedBooks.Remove(book2); // Now we must get "Remove" event, since item index can be found Assert.AreEqual(NotifyCollectionChangedAction.Remove, lastChangeAction); Assert.AreSame(book1.RelatedBooks, lastSenderCollection); } ResetLastXxx(); book1.RelatedBooks.Clear(); Assert.AreEqual(NotifyCollectionChangedAction.Reset, lastChangeAction); Assert.AreSame(book1.RelatedBooks, lastSenderCollection); ResetLastXxx(); session.NotifyChanged(); Assert.AreEqual(null, lastChangedProperty); Assert.AreSame(book2, lastSenderObject); Assert.AreEqual(NotifyCollectionChangedAction.Reset, lastChangeAction); Assert.AreSame(book1.RelatedBooks, lastSenderCollection); // tx.Complete(); } }
public void MainTest() { var config = DomainConfigurationFactory.CreateWithoutSessionConfigurations(); config.UpgradeMode = DomainUpgradeMode.Recreate; config.Types.Register(typeof(Person).Assembly, typeof(Person).Namespace); var domain = Domain.Build(config); using (var session = domain.OpenSession()) using (var transactionScope = session.OpenTransaction()) { var employee = new Person(session) { Name = "Employee", Photo = new byte[] { 8, 0 } }; var manager = new Person(session) { Name = "Manager", Photo = new byte[] { 8, 0 } }; manager.Employees.Add(employee); transactionScope.Complete(); } using (var session = domain.OpenSession()) using (var transactionScope = session.OpenTransaction()) { var persons = session.Query.All <Person>() .Prefetch(p => p.Photo) // Lazy load field .Prefetch(p => p.Employees // EntitySet Employees .Prefetch(e => e.Photo)) // and lazy load field of each of its items .Prefetch(p => p.Manager); // Referenced entity foreach (var person in persons) { // some code here... } transactionScope.Complete(); } using (var session = domain.OpenSession()) using (var transactionScope = session.OpenTransaction()) { var personIds = session.Query.All <Person>().Select(p => p.Id); var prefetchedPersons = session.Query.Many <Person, int>(personIds) .Prefetch(p => new { p.Photo, p.Manager }) // Lazy load field and Referenced entity .Prefetch(p => p.Employees // EntitySet Employees .Prefetch(e => new { e.Photo, e.Manager })); // and lazy load field and referenced entity of each of its items foreach (var person in prefetchedPersons) { // some code here... } transactionScope.Complete(); } using (var session = domain.OpenSession()) using (var transactionScope = session.OpenTransaction()) { var persons = session.Query.All <Person>() .Prefetch(p => p.Photo) // Lazy load field .Prefetch(p => p.Employees.Prefetch(e => e.Photo)) // EntitySet Employees and lazy load field of each of its items with the limit on number of items to be loaded .Prefetch(p => p.Manager.Photo); // Referenced entity and lazy load field for each of them foreach (var person in persons) { Assert.IsTrue(DirectStateAccessor.Get(person).GetFieldState("Photo") == PersistentFieldState.Loaded); Assert.IsTrue(DirectStateAccessor.Get(person).GetFieldState("Manager") == PersistentFieldState.Loaded); if (person.ManagerKey != null) { Assert.IsNotNull(DirectStateAccessor.Get(session)[person.ManagerKey]); Assert.IsTrue(DirectStateAccessor.Get(person.Manager).GetFieldState("Photo") == PersistentFieldState.Loaded); } // some code here... } transactionScope.Complete(); } }