public async Task Given_SingleEntity_Should_TimeTravel() { var context = TestHelper.GetNewDbContext(); var appleId = Guid.Parse("00000002-8803-4263-ada6-cd12a33d8872"); context.Apples.Add(new Apple { Id = appleId, FruitStatus = FruitStatus.Ripe }); await context.SaveChangesAsync(); var ripeAppleTime = TestHelper.UtcNow; context = TestHelper.GetNewDbContext(); var ripeApple = await context.Apples.SingleAsync(a => a.Id == appleId); ripeApple.FruitStatus = FruitStatus.Rotten; await context.SaveChangesAsync(); context = TestHelper.GetNewDbContext(); var currentApple = await context.Apples.AsNoTracking().SingleAsync(a => a.Id == appleId); currentApple.FruitStatus.Should().Be(FruitStatus.Rotten); using (TemporalQuery.AsOf(ripeAppleTime)) { var timeTravelApple = await context.Apples.AsNoTracking().SingleAsync(a => a.Id == appleId); timeTravelApple.FruitStatus.Should().Be(FruitStatus.Ripe); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unchecked") @Override public <R> R query(java.time.temporal.TemporalQuery<R> query) public override R query <R>(TemporalQuery <R> query) { if (query == TemporalQueries.ZoneId()) { return((R)Zone); } else if (query == TemporalQueries.Chronology()) { return((R)Chrono); } else if (query == TemporalQueries.LocalDate()) { return((R)(Date != java.time.temporal.TemporalAccessor_Fields.Null ? LocalDate.From(Date) : java.time.temporal.TemporalAccessor_Fields.Null)); } else if (query == TemporalQueries.LocalTime()) { return((R)Time); } else if (query == TemporalQueries.Zone() || query == TemporalQueries.Offset()) { return(query.QueryFrom(this)); } else if (query == TemporalQueries.Precision()) { return(java.time.temporal.TemporalAccessor_Fields.Null); // not a complete date/time } // inline TemporalAccessor.super.query(query) as an optimization // non-JDK classes are not permitted to make this optimization return(query.QueryFrom(this)); }
//----------------------------------------------------------------------- /// <summary> /// Queries this offset using the specified query. /// <para> /// This queries this offset using the specified query strategy object. /// The {@code TemporalQuery} object defines the logic to be used to /// obtain the result. Read the documentation of the query to understand /// what the result of this method will be. /// </para> /// <para> /// The result of this method is obtained by invoking the /// <seealso cref="TemporalQuery#queryFrom(TemporalAccessor)"/> method on the /// specified query passing {@code this} as the argument. /// /// </para> /// </summary> /// @param <R> the type of the result </param> /// <param name="query"> the query to invoke, not null </param> /// <returns> the query result, null may be returned (defined by the query) </returns> /// <exception cref="DateTimeException"> if unable to query (defined by the query) </exception> /// <exception cref="ArithmeticException"> if numeric overflow occurs (defined by the query) </exception> //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unchecked") @Override public <R> R query(java.time.temporal.TemporalQuery<R> query) public override R query <R>(TemporalQuery <R> query) { if (query == TemporalQueries.Offset() || query == TemporalQueries.Zone()) { return((R)this); } return(TemporalAccessor.this.query(query)); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unchecked") @Override public <R> R query(java.time.temporal.TemporalQuery<R> query) public override R query <R>(TemporalQuery <R> query) { if (query == TemporalQueries.ZoneId()) { return((R)ZoneId.this); } return(TemporalAccessor.this.query(query)); }
//----------------------------------------------------------------------- /// <summary> /// Queries this month-day using the specified query. /// <para> /// This queries this month-day using the specified query strategy object. /// The {@code TemporalQuery} object defines the logic to be used to /// obtain the result. Read the documentation of the query to understand /// what the result of this method will be. /// </para> /// <para> /// The result of this method is obtained by invoking the /// <seealso cref="TemporalQuery#queryFrom(TemporalAccessor)"/> method on the /// specified query passing {@code this} as the argument. /// /// </para> /// </summary> /// @param <R> the type of the result </param> /// <param name="query"> the query to invoke, not null </param> /// <returns> the query result, null may be returned (defined by the query) </returns> /// <exception cref="DateTimeException"> if unable to query (defined by the query) </exception> /// <exception cref="ArithmeticException"> if numeric overflow occurs (defined by the query) </exception> //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unchecked") @Override public <R> R query(java.time.temporal.TemporalQuery<R> query) public override R query <R>(TemporalQuery <R> query) { if (query == TemporalQueries.Chronology()) { return((R)IsoChronology.INSTANCE); } return(TemporalAccessor.this.query(query)); }
/// <summary> /// Gets a value using a query. /// </summary> /// <param name="query"> the query to use, not null </param> /// <returns> the result, null if not found and optional is true </returns> /// <exception cref="DateTimeException"> if the type is not available and the section is not optional </exception> internal R getValue <R>(TemporalQuery <R> query) { R result = Temporal_Renamed.query(query); if (result == null && Optional == 0) { throw new DateTimeException("Unable to extract value: " + Temporal_Renamed.GetType()); } return(result); }
private static async Task AssertWormlessFruitStatusAtTime( FruitStatus expectedFruitStatus, DateTime appleTime, Guid appleId) { using (TemporalQuery.AsOf(appleTime)) { var apple = await GetApple(appleId); apple .Should() .BeEquivalentTo(new { FruitStatus = expectedFruitStatus, Worms = Array.Empty <Worm>() }, options => options.ExcludingMissingMembers()); } }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unchecked") @Override public <R> R query(java.time.temporal.TemporalQuery<R> query) public override R query <R>(TemporalQuery <R> query) { if (query == TemporalQueries.Chronology()) { return((R)EffectiveChrono); } if (query == TemporalQueries.ZoneId()) { return((R)EffectiveZone); } if (query == TemporalQueries.Precision()) { return(Temporal.query(query)); } return(query.QueryFrom(this)); }
public async Task Given_IncludedCollection_Should_TimeTravelIncludedCollection() { var context = TestHelper.GetNewDbContext(); var appleId = Guid.Parse("00000003-8803-4263-ada6-cd12a33d8872"); var apple = new Apple { Id = appleId, FruitStatus = FruitStatus.Rotten }; apple.AddWorm("Gav"); context.Apples.Add(apple); await context.SaveChangesAsync(); var rottenAppleTime = TestHelper.UtcNow; context = TestHelper.GetNewDbContext(); apple = await context.Apples.SingleAsync(a => a.Id == appleId); apple.AddWorm("G-Dog"); apple.AddWorm("Gavin' A Laugh"); await context.SaveChangesAsync(); context = TestHelper.GetNewDbContext(); var currentApple = await context.Apples .Include(a => a.Worms) .SingleAsync(a => a.Id == appleId); currentApple.Worms.Count.Should().Be(3); using (TemporalQuery.AsOf(rottenAppleTime)) { // Let's use the same context for time travel var timeTravelApple = await context.Apples .Include(a => a.Worms) // All temporal queries must be .AsNoTracking() .AsNoTracking() .SingleAsync(a => a.Id == appleId); timeTravelApple.Worms.Count.Should().Be(1); } }
private static async Task AssertWormsNavigationPropertyAtRottenAppleTime(DateTime rottenAppleTime, Guid appleId) { using (TemporalQuery.AsOf(rottenAppleTime)) { using var localScope = ServiceProvider.CreateScope(); var context = localScope.ServiceProvider.GetService <ApplicationDbContext>(); var rottenAppleWorms = await context.Apples .Where(a => a.Id == appleId) .SelectMany(a => a.Worms) .Include(worm => worm.Weapons) .AsNoTracking().ToListAsync(); rottenAppleWorms .Should() .BeEquivalentTo(new[] { new { Name = "Moe", Weapons = new[] { new { Name = "Bazooka" } } } }, options => options.ExcludingMissingMembers()); } }
public async Task TemporalQuery_Should_AllowAllTemporalEntitiesToTimeTravel() { var(appleId, unripeAppleTime, ripeAppleTime, rottenAppleTime) = await SimulateLifecycleOfMyApple(); // Validate current state of my apple var currentApple = await GetApple(appleId); currentApple .Should() .BeEquivalentTo( new { FruitStatus = FruitStatus.Fuzzy, Worms = new object[] { new { Name = "Hairy", Weapons = new[] { new { Name = "Holy Hand Grenade" }, new { Name = "Super Banana Bomb" } }, FriendsNames = new[] { "Joan", "Starr", "Curly" } }, new { Name = "Curly" }, new { Name = "Moe", Weapons = new[] { new { Name = "Bazooka Pie" } }, FriendsNames = new[] { "John" } } } }, options => options.ExcludingMissingMembers()); // Query the state of my apple a prior "system time" when the apple was rotten using (TemporalQuery.AsOf(rottenAppleTime)) { var rottenApple = await GetApple(appleId); rottenApple .Should() .BeEquivalentTo( new { FruitStatus = FruitStatus.Rotten, Worms = new object[] { new { Name = "Moe", Weapons = new[] { new { Name = "Bazooka" } }, FriendsNames = new[] { "John", "Ringo" } } } }, options => options.ExcludingMissingMembers()); } await Task.WhenAll(new[] { AssertWormlessFruitStatusAtTime(FruitStatus.Ripe, ripeAppleTime, appleId), AssertWormlessFruitStatusAtTime(FruitStatus.Unripe, unripeAppleTime, appleId), AssertWormsNavigationPropertyAtRottenAppleTime(rottenAppleTime, appleId) }); }