public void Queryable_AsTracking()
        {
            // TODO: ZZZ - We have hard time to debug it due to .Value that execute without debug work?

            TestContext.DeleteAll(x => x.Entity_Basics, TestContext.EffortConnection);
            TestContext.Insert(x => x.Entity_Basics, 10, TestContext.EffortConnection);

            using (var ctx = new TestContext(TestContext.EffortConnection))
            {
                // BEFORE
                var futureValue1 = ctx.Entity_Basics.Where(x => x.ColumnInt < 5).OrderBy(x => x.ColumnInt).FutureValue();
                var futureValue2 = ctx.Entity_Basics.Where(x => x.ColumnInt >= 5).OrderBy(x => x.ColumnInt).FutureValue();

                // TEST: The batch contains 2 queries
                Assert.AreEqual(2, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count);

                var value = futureValue1.Value;

                // AFTER

                // TEST: The batch contains 2 queries
                Assert.AreEqual(0, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count);

                // TEST: The futureList1 has a value and the first item is returned
                Assert.IsTrue(futureValue1.HasValue);
                Assert.AreEqual(0, value.ColumnInt);

                // TEST: The futureList2 has a value and the first item is returned
                Assert.IsTrue(futureValue2.HasValue);
                Assert.AreEqual(5, futureValue2.Value.ColumnInt);

                // TEST: The first item of both FutureValue has been added
                Assert.AreEqual(2, ctx.ChangeTracker.Entries().Count());
            }
        }
        public void Queryable_AsNoTracking()
        {
            TestContext.DeleteAll(x => x.Entity_Basics);
            TestContext.Insert(x => x.Entity_Basics, 10);

            using (var ctx = new TestContext())
            {
                // BEFORE
                var futureValue1 = ctx.Entity_Basics.Where(x => x.ColumnInt < 5).OrderBy(x => x.ColumnInt).AsNoTracking().FutureValue();
                var futureValue2 = ctx.Entity_Basics.Where(x => x.ColumnInt >= 5).OrderBy(x => x.ColumnInt).AsNoTracking().FutureValue();

                // TEST: The batch contains 2 queries
                Assert.AreEqual(2, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count);

                var value = futureValue1.Value;

                // AFTER

                // TEST: The batch contains 0 queries
                Assert.AreEqual(0, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count);

                // TEST: The futureList1 has a value and the first item is returned
                Assert.IsTrue(futureValue1.HasValue);
                Assert.AreEqual(0, value.ColumnInt);

                // TEST: The futureList2 has a value and the first item is returned
                Assert.IsTrue(futureValue2.HasValue);
                Assert.AreEqual(5, futureValue2.Value.ColumnInt);

                // TEST: No entries has been loaded in the change tracker
                Assert.AreEqual(0, ctx.ChangeTracker.Entries().Count());
            }
        }
        public void DelayedQuery_AsTracking()
        {
            TestContext.DeleteAll(x => x.Entity_Basics, TestContext.EffortConnection);
            TestContext.Insert(x => x.Entity_Basics, 10, TestContext.EffortConnection);

            using (var ctx = new TestContext(TestContext.EffortConnection))
            {
                // BEFORE
                var futureValue1 = ctx.Entity_Basics.Where(x => x.ColumnInt < 5).DeferredCount().FutureValue();
                var futureValue2 = ctx.Entity_Basics.Where(x => x.ColumnInt >= 5).DeferredCount().FutureValue();

                // TEST: The batch contains 2 queries
                Assert.AreEqual(2, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count);

                var value = futureValue1.Value;

                // AFTER

                // TEST: The batch contains 0 queries
                Assert.AreEqual(0, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count);

                // TEST: The futureValue1 has a value and the count equal 5
                Assert.IsTrue(futureValue1.HasValue);
                Assert.AreEqual(5, value);

                // TEST: The futureValue2 has a value and the count equal 5
                Assert.IsTrue(futureValue2.HasValue);
                Assert.AreEqual(5, futureValue2.Value);

                // TEST: No entries has been loaded in the change tracker (A value is returned, not an entity)
                Assert.AreEqual(0, ctx.ChangeTracker.Entries().Count());
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        ///     Defer the execution of the <paramref name="query" /> and batch the query command with other
        ///     future queries. The batch is executed when a future query requires a database round trip.
        /// </summary>
        /// <typeparam name="TResult">The type of the query result.</typeparam>
        /// <param name="query">The query to defer the execution and to add in the batch of future queries.</param>
        /// <returns>
        ///     The QueryFutureValue&lt;TResult,TResult&gt; added to the batch of futures queries.
        /// </returns>
        public static QueryFutureValue <TResult> FutureValue <TResult>(this QueryDeferred <TResult> query)
        {
            if (!QueryFutureManager.AllowQueryBatch)
            {
                var futureValue = new QueryFutureValue <TResult>(null, null);
                futureValue.GetResultDirectly(query.Query);
                return(futureValue);
            }

#if EF5 || EF6
            var objectQuery = query.Query.GetObjectQuery();
            var futureBatch = QueryFutureManager.AddOrGetBatch(objectQuery.Context);
            var futureQuery = new QueryFutureValue <TResult>(futureBatch, objectQuery);
#elif EFCORE
            QueryFutureBatch           futureBatch;
            QueryFutureValue <TResult> futureQuery;
            if (query.Query.IsInMemoryQueryContext())
            {
                var context = query.Query.GetInMemoryContext();
                futureBatch                       = QueryFutureManager.AddOrGetBatch(context);
                futureBatch.IsInMemory            = true;
                futureQuery                       = new QueryFutureValue <TResult>(futureBatch, query.Query);
                futureQuery.InMemoryDeferredQuery = query;
            }
            else
            {
                var context = query.Query.GetDbContext();
                futureBatch = QueryFutureManager.AddOrGetBatch(context);
                futureQuery = new QueryFutureValue <TResult>(futureBatch, query.Query);
            }
#endif
            futureBatch.Queries.Add(futureQuery);

            return(futureQuery);
        }
        public void Queryable_AsTracking()
        {
            TestContext.DeleteAll(x => x.Entity_Basics);
            TestContext.Insert(x => x.Entity_Basics, 10);

            using (var ctx = new TestContext())
            {
                // BEFORE
                var futureList1 = ctx.Entity_Basics.Where(x => x.ColumnInt < 5).Future();
                var futureList2 = ctx.Entity_Basics.Where(x => x.ColumnInt >= 5).Future();

                // TEST: The batch contains 2 queries
                Assert.AreEqual(2, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count);

                var list = futureList1.ToList();

                // AFTER

                // TEST: The batch contains 0 queries
                Assert.AreEqual(0, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count);

                // TEST: The futureList1 has a value and the list contains 5 items
                Assert.IsTrue(futureList1.HasValue);
                Assert.AreEqual(5, futureList1.ToList().Count);
                Assert.AreEqual(5, list.Count);

                // TEST: The futureList2 has a value and the list contains 5 items
                Assert.IsTrue(futureList2.HasValue);
                Assert.AreEqual(5, futureList2.ToList().Count);

                // TEST: All entries has been loaded in the change tracker
                Assert.AreEqual(10, ctx.ChangeTracker.Entries().Count());
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        ///     Defer the execution of the <paramref name="query" /> and batch the query command with other
        ///     future queries. The batch is executed when a future query requires a database round trip.
        /// </summary>
        /// <typeparam name="TResult">The type of the query result.</typeparam>
        /// <param name="query">The query to defer the execution and to add in the batch of future queries.</param>
        /// <returns>
        ///     The QueryFutureValue&lt;TResult,TResult&gt; added to the batch of futures queries.
        /// </returns>
        public static QueryFutureValue <TResult> FutureValue <TResult>(this QueryDeferred <TResult> query)
        {
#if EF5 || EF6
            var objectQuery = query.Query.GetObjectQuery();
            var futureBatch = QueryFutureManager.AddOrGetBatch(objectQuery.Context);
            var futureQuery = new QueryFutureValue <TResult>(futureBatch, objectQuery);
#elif EF7
            var context     = query.Query.GetDbContext();
            var futureBatch = QueryFutureManager.AddOrGetBatch(context);
            var futureQuery = new QueryFutureValue <TResult>(futureBatch, query.Query);
#endif
            futureBatch.Queries.Add(futureQuery);

            return(futureQuery);
        }
        public async Task Queryable_ConcatWithOrderBy_AsNoTracking()
        {
            TestContext.DeleteAll(x => x.Entity_Basics);
            TestContext.Insert(x => x.Entity_Basics, 10);

            TestContext.DeleteAll(x => x.Entity_Guids);
            TestContext.Insert(x => x.Entity_Guids, 10);

            using (var ctx = new TestContext())
            {
                var future1 = ctx.Entity_Basics
                              .Select(eb => eb.ID)
                              .Concat(ctx.Entity_Guids.Select(i => i.ColumnInt).Future())
                              .OrderBy(x => x)
                              .Future();

                var future2 = ctx.Entity_Basics
                              .Select(eb => eb.ID)
                              .Concat(ctx.Entity_Guids.Select(i => i.ColumnInt).Future())
                              .OrderBy(x => x)
                              .Future();

                // DOESN'T WORK with ToListAsync()... due to having 2 queries... we don't care, use the non async
                var noFutureResult = await ctx.Entity_Basics
                                     .Select(eb => eb.ID)
                                     .Concat(ctx.Entity_Guids.Select(i => i.ColumnInt).Future())
                                     .OrderBy(x => x)
                                     .ToListAsync();

                Assert.AreEqual(2, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count);

                var futureResult1 = await future1.ToListAsync();

                var futureResult2 = await future2.ToListAsync();

                Assert.AreEqual(0, QueryFutureManager.AddOrGetBatch(ctx.GetObjectContext()).Queries.Count);

                Assert.IsTrue(future1.HasValue);
                Assert.IsTrue(future2.HasValue);

                CollectionAssert.AreEqual(noFutureResult, futureResult1);
                CollectionAssert.AreEqual(noFutureResult, futureResult2);
            }
        }